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

时间:2017-12-11 23:29:07

标签: c++ templates casting template-specialization

上下文:我有一个属性包,它有公共方法来接受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 个答案:

答案 0 :(得分:2)

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

编写一个只有地图添加的函数:

void add(std::string const & name, bool value)
{
m_content.boolProperties[name] = value;
}
// And one for others
void add(std::string const &, ...)
{
// failure
}

答案 1 :(得分:1)

如果你坚持使用11之前的c ++,你可以使用reinterpret_cast&lt;&gt ;.这应该是一个安全的演员,因为你刚刚检查过它。

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

但这不是正确的做法。你应该让类型系统做出艰苦的工作。我可以访问m_content的类型。我建议你创建这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;
   }

您的添加功能将变为:

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);
}