2014-09-13 64 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引用。如果有人在其中定義了官方文件,請在此張貼鏈接。希望這個答案能夠幫助其他人。