2013-08-30 58 views
5

我有一個類,我已經寫了哪種類型的擦除。公共接口是:爲什麼這個模糊不清?

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:值「不能從轉換'到std :: string的」

沒有構造函數可採取源類型,或者如果我註釋掉的模板轉換運算符,並添加operator std::string() const構造函數重載解析模棱兩可

然後編譯。我認爲,std :: string構造函數和模板化的演員操作符之間具有相同的匹配優點。任何人都可以提出發生了什麼事以及如何解決它?

+0

錯誤消息是否顯示候選人? –

+3

請提供一個編譯示例(儘可能多達相關錯誤)。 –

+1

這是我寫的一個小例子:http://codepad.org/XJ2Jv5fT – Dave

回答

6

伊戈爾解釋了這個問題。這裏是我建議的解決方案:

你的類顯然只是用來一次存儲一種類型的對象,所以明確說明。一個真正的函數替換轉換功能:

template <typename T> 
T get() const; 

現在這樣稱呼它:

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

沒有歧義。沒有機會錯誤的功能被調用,並搞亂了一切。我認爲它現在更具可讀性。

6

std::string有幾個構造函數可以用一個參數調用 - 例如,一個採取const string&,另一個採取const char*。那麼T應該解決什麼呢?

從C++標準:

5.2.9p4否則,表達式e可以顯式轉換到使用所述形式static_cast<T>(e)static_cast類型T如果聲明T t(e);是良好的,對一些發明臨時變量t

在你的情況下,聲明std::string t(val);是不合格的。

+0

'std :: string',由演員提供。它的構造依賴於函數中的代碼。 –

+0

我可以看到這個答案是什麼意思,但對我來說,它選擇遵循直接(單階段)轉換爲'std :: string'優先於任何間接(兩階段)轉換爲一個可以傳遞給'std :: string'構造函數的參數 – Dave

+0

@Neil Kirk:「5.2.9p4否則,表達式'e'可以使用表單的'static_cast'明確地轉換爲類型'T' (e)'如果聲明'T t(e);'是對於一些發明的臨時變量't'的格式良好的'static_cast 。在這種情況下,聲明'string t(val);'的格式不正確。 –

5

以下使用std :: string(如果可以返回引用)。

static_cast<const std::string&>(val); 
+0

證實http://codepad.org/w7VKXUcs。這很有趣。我不會想到要參考。雖然不是很可讀,所以我會在真正的代碼中避免它,除非絕對必要。 – Dave

+0

非常有趣和新穎的解決方案! –

相關問題