我有一个我写过的类,它会进行类型擦除。公共界面是:
template <typename T>
value(const T &t);
value(value &&v);
template <typename T>
operator T() const;
当我从std :: string创建一个值实例时,我没有任何问题,一切都按预期工作。当我尝试恢复std :: string时,使用static_cast<std::string>(val)
,其中val
是一个持有std :: string的值的实例,我从VS2012获得以下错误:
错误C2440:'static_cast':无法从'value'转换为std :: string'
没有构造函数可以获取源类型,或构造函数重载解析不明确
如果我注释掉模板化的强制转换运算符并添加operator std::string() const
,那么它就会编译。我认为std :: string构造函数和模板化的强制转换运算符之间的某些东西具有相同的匹配优势。任何人都可以建议发生了什么以及如何解决它?
答案 0 :(得分:6)
std::string
有几个能够用一个参数调用的构造函数 - 例如一个人const string&
,另一个人const char*
。那么T
应该解决什么呢?
来自C ++标准:
5.2.9p4否则,如果声明
T
格式正确,则可以使用static_cast
形式的static_cast<T>(e)
将表达式e显式转换为T t(e);
类型,对于一些发明的临时变量t
。
在您的情况下,声明std::string t(val);
格式不正确。
答案 1 :(得分:6)
您的类显然只是一次存储一种类型的对象,因此请明确说明。用真实函数替换转换函数:
template <typename T>
T get() const;
现在这样称呼:
std::string myString = myValue.get<std::string>( );
没有歧义。没有机会调用错误的功能并弄乱一切。而且我认为它现在更具可读性。
答案 2 :(得分:5)
以下使用std :: string(如果可以返回引用)。
static_cast<const std::string&>(val);