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