2014-09-13 62 views
1

我有一段代码在VS2008中成功编译,无法在VS2013中编译。VS2013中的转换运算符错误C2678,在VS2008中工作

有一个类Data::CData这是一个变体类型的实现。它有一个转换运算符重载:

template<class T> T&  GetValue(); 
template<class T> const T& GetValue() const; 
template<class T> operator T&() { return GetValue<T>(); } 
template<class T> operator const T&() const { return GetValue<T>(); } 

产生的错误的代码是

Data::CData Val; 
Data::PParams Prm = (const Data::PParams&)Val; 

的错误是:错误C2678:二进制“=”:没有操作员发现它接受一个左边的操作数类型'const Data :: PParams'(或者没有可接受的转换)。

而这种代码编译成功通过两种编译器:

Data::CData Val; 
Data::PParams Prm = Val.operator const Data::PParams&(); 

我该怎么办错了吗?

的例子,再现了一个问题:https://www.dropbox.com/s/zjohnu5v87tyr2c/ConstOverload.zip?dl=0

+0

对于那个强制转换,重载决议应该选择'运算符T&()','T'推导为'const Data :: PParams'。在不知道“GetValue”和“Data :: PParams”的定义的情况下,很难说很多,但是如果你不期待它,那么额外的'const'限定符可能会搞砸了。 – 2014-09-13 01:39:28

+0

旧式的演员阵容可能并不总能满足你的期望。改用static_cast,看看它是否改变了行为。但是,为什么不直接调用'GetValue <>'? – 2014-09-13 04:17:10

+0

我还想到了Visual C++中的一个bug(故意扩展),它允许在不允许的情况下绑定const引用。也许这会消失在一个更新的版本,旧的行为依赖于此。在任何情况下,右值引用的加入都会使得这些事情出现不同;他们可能需要解决小问题才能让新的更复杂的规则正常工作。 – 2014-09-13 04:19:53

回答

1

我终于得到了一个解决方案! 相反的两个操作符重载我用

template<class T> operator T&() { return GetValue<T>(); } 
template<class T> operator const T&() const { return GetValue<T>(); } 

应该有

template<class T> operator T&() { return GetValue<T>(); } 
template<class T> operator const T&() { return GetValue<T>(); } 
template<class T> operator const T&() const { return GetValue<T>(); } 

所以,在VS2013我们还需要一个专门的接线员给非const对象const引用。如果有人在其中定义了官方文件,请在此张贴链接。希望这个答案能够帮助其他人。