7

我有一个我写过的类,它可以进行类型擦除。公共接口是:

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 构造函数和模板化强制转换运算符之间的某些东西具有相同的匹配度。谁能建议正在发生的事情以及如何解决它?

4

3 回答 3

7

std::string有几个能够用一个参数调用的构造函数——例如一个接受const string&,另一个接受const char*。那应该怎么T解决呢?

从 C++ 标准:

5.2.9p4 否则,对于某些发明的临时变量,如果声明格式正确,则表达式 e 可以T使用static_cast形式的 a 显式转换为类型。static_cast<T>(e)T t(e);t

在您的情况下,声明格式std::string t(val);不正确。

于 2013-08-30T17:34:53.843 回答
7

伊戈尔解释了这个问题。这是我建议的解决方案:

您的类显然只打算一次存储一种类型的对象,因此请明确说明。用实函数替换转换函数:

template <typename T>
T get() const;

现在这样称呼它:

std::string myString = myValue.get<std::string>( );

没有歧义。没有机会调用错误的函数并搞砸一切。我认为它现在更具可读性。

于 2013-08-30T17:57:19.417 回答
5

以下适用于 std::string (如果您可以返回参考)。

static_cast<const std::string&>(val);
于 2013-08-30T18:01:48.807 回答