当前位置: 首页 > 知识库问答 >
问题:

为什么我的模板专业化检查不足以正确处理相应的类型?

叶元凯
2023-03-14

上下文:我有一个属性包,其中包含接受int、bool和string属性的公共方法。它们都调用模板私有函数,其片段附在下面。

问题:我正在检查模板专门化以将属性添加到相应的映射中。但代码为C2440的编译器错误“无法从字符串转换为int”和C2440“无法从字符串转换为bool”。我不知道为什么会有这个问题。

尝试解决:我尝试静态强制转换,但它似乎有错误,它不能强制转换,因为它不能从字符串转换为int(或bool!)。

template <typename T>
void PropertyBag::Add(const string& name, const T value)
{
    string errorMessage;
    if (!IsValidPropertyName(name, errorMessage))
    {
        m_pFailureHandler->Handle(errorMessage);
        return;
    }

    if (!IsPropertyNameUnique(name, m_content))
    {
        m_pFailureHandler->Handle("Property '" + name + "' is not unique");
        return;
    }

    if (is_same<T, int32_t>::value)
        m_content.intProperties[name] = value;
    else if (is_same<T, string>::value)
        m_content.stringProperties[name] = value;
    else if (is_same<T, bool>::value)
        m_content.boolProperties[name] = value;
    else
        m_pFailureHandler->Handle("Unsupported value type");
}

共有2个答案

司空福
2023-03-14

如果你坚持使用11 c之前的版本,你可以使用reinterpret_cast

if (is_same<T, int32_t>::value)
    m_content.intProperties[name] = *reinterpret_cast<const int32_t*>(&value);
// etc...

但这不是正确的方法。你应该让打字系统来完成繁重的工作。我想你可以访问m_内容的类型。我建议您创建以下3个重载:

struct Content
{
   void setproperty(const std::string& name, bool b)
   {
       boolProperties[name] = b;
   }

   void setproperty(const std::string& name, int32_t n)
   {
       intProperties[name] = n;
   }

   void setproperty(const std::string& name, const std::string& s)
   {
       stringProperties[name] = s;
   }
};

如果您不能更改内容,您可以创建免费功能

   void setproperty(Content& content, const std::string& name, bool b)
   {
       content.boolProperties[name] = b;
   }

   void setproperty(Content& content, const std::string& name, int32_t n)
   {
       content.intProperties[name] = n;
   }

   void setproperty(Content& content, const std::string& name, const std::string& s)
   {
       content.stringProperties[name] = s;
   }

然后,您的add函数变为:

template <typename T>
void PropertyBag::Add(const string& name, const T value)
{
    string errorMessage;
    if (!IsValidPropertyName(name, errorMessage))
    {
        m_pFailureHandler->Handle(errorMessage);
        return;
    }

    if (!IsPropertyNameUnique(name, m_content))
    {
        m_pFailureHandler->Handle("Property '" + name + "' is not unique");
        return;
    }
    setProperty(m_content, name, value);        
    // or m_content.setProperty(name, value);
}
刘辰钊
2023-03-14

您的问题是您等到函数体才进行测试,整个函数体必须能够编译,它不会修剪无法运行的if语句的主体。

编写一个除了map之外什么都不是的函数添加:

void add(std::string const & name, bool value)
{
m_content.boolProperties[name] = value;
}
// And one for others
void add(std::string const &, ...)
{
// failure
}
 类似资料:
  • 问题内容: 这是我的代码: 它运作良好。但是当我尝试添加这个 我遇到编译器错误:«int MyClass :: DoSomething()»的«>»令牌模板标识«DoSomething <0>»之前的无效显式专门化与任何模板声明都不匹配 我使用g ++ 4.6.1应该怎么做? 问题答案: 不幸的是,如果不对外部模板进行特殊化处理,就不能对作为类模板成员的模板进行特殊处理: C ++ 11 14.7

  • 这个问题可能太难在标题中的on句子中描述,但这里有一个最小的例子: 当两种类型相同时 当这两种类型是同一类型的类模板的实例化时 天真地说,我们希望第二个部分专门化不会与第一个不明确,因为它感觉“更专门化”,对基础模板上和的推导类型施加更多限制。然而,主要的编译器似乎同意我们的期望是错误的:为什么它不被认为是更专业化的?

  • 这非常适合 然后我试着看看我是否可以用CRTP基来专门化 这不起作用,我得到“静态断言失败:不知道如何格式化类型”,两个类型之间没有有效的转换,我想这是因为显式模板转换问题。我试着 我得到了一个关于“模板参数在部分专门化中不可推导”的错误:好吧,所以接下来我尝试 似乎完全跳过类型,我得到我得到“静态断言失败:不知道如何格式化类型”。所以我试着 我得到了“错误:模板参数在部分专门化中不可推导”,然后

  • 函数模板专门化的主模板通常很直观,然而,我正在寻找形式规则来理解更令人惊讶的情况。例如: 理论上,(3)也可以是(1)的特化,但实验表明不是。

  • 我有一个将类型与整数值相关联的trait类。 我正在编写一个模板函数,返回类型由上面的traits类提供,并将其专门化为各种int值: 这可以与VS2015一起编译(参见https://godbolt.org/z/LpZnni)但VS2017并没有抱怨: 错误C2912:显式专门化的int函数 令我惊讶的是,像下面这样声明一个非模板函数会编译: 将公开可以解决编译问题,但我不明白为什么。对我来说,

  • 还尝试在专门化的中进行模板方法专门化: 这一次它编译,但调用原始方法,即 解决方案