2014-02-17 15 views
4

鑑於以下代碼:在新的初始化程序存在的情況下,運算符重載解析如何工作?

#include <iostream> 
#include <vector> 

template <typename Source> 
class ConvertProxy 
{ 
    Source const* m_source; 
public: 
    ConvertProxy(Source const& source) 
     : m_source(&source) 
    { 
    } 

    template <typename Dest> 
    operator Dest() const 
    { 
     return Dest(m_source->begin(), m_source->end()); 
    } 
}; 

template <typename Source> 
ConvertProxy<Source> convert(Source const& source) 
{ 
    return ConvertProxy<Source>(source); 
} 

int 
main() 
{ 
    std::vector<int> src; 
    for (int i = 0; i != 5; ++ i) { 
     src.push_back(i); 
    } 
    std::vector<double> dest = convert(src); /* XXX */ 
    for (std::vector<double>::const_iterator i = dest.begin(), e = dest.end(); 
      i != e; 
      ++ i) { 
     std::cout << *i << std::endl; 
    } 
    return 0; 
} 

是本合法在C++ 11,或者是線標記XXX曖昧?

同樣的問題,但與標記行改爲:

std::vector<double> dest(convert(src)); 

std::vector<double> dest; 
dest = convert(src); 

在預C++ 11,我認爲第二是非法的,但其他兩個 絕對不是。

FWIW:克++(4.8.2)接受第一,但不是其他兩個(具有 -std=c++11;否則,它接受第一和第三,但 不是第二)。 VS 2013接受所有的人,但智能感知 標記所有的人都是錯誤的(這是什麼觸發了我的興趣 :你得到一個不錯的紅色滾動條的標記,與 符號紅色下劃線,但代碼編譯完美)。換句話說:三種編譯器和三種不同的行爲。

(對於那些誰不知道,爲什麼:這是獲取上下文—賦值的左手邊, 例如—參與重載標準成語 )

+0

您的第一個替代品'std :: vector dest(convert(src));'可能是不明確的,因爲[最煩人的解析](http://en.wikipedia.org/wiki/Most_vexing_parse)問題。 – CouchDeveloper

+0

@CouchDeveloper對於最令人頭痛的問題,解析被捲入,'convert'必須命名類型。它沒有。我認爲,第一替換(第二版)是(並且一直)曖昧,其具有可與單個參數來調用多個構造的任何類型。儘可能少的,Visual Studio 2013接受它(並調用我想要的轉換)。我正在尋找的是能夠向我解釋新的'initializer_list'構造函數如何介入的人。一些WRT rvalue-ref ctor將會很好,儘管我想我理解他們。 –

+0

我可以看到'initializer_list'正在使用的唯一的地方是在返回值:不是'ConvertProxy (源)'你可以只寫'{源}'但是那是因爲你知道從返回類型。同樣對於這個特定的問題,ConvertProxy有什麼意義,爲什麼不使用一個帶有typename destination的轉換函數。 – Gasim

回答

0

有歧義在必須首先解決的編譯代碼方面,我不認爲C++ 11標準爲此添加了任何內容。

您應該使用容器的完整定義作爲模板模板參數以進行替換以進行匹配;最明確的一個是:

template <typename T, typename A, template <typename, typename> class Dest> 
operator Dest<T, A>() const 
{ 
    return Dest<T, A>(m_source->begin(), m_source->end()); 
} 

所有這三種情況下進行編譯,並且取代與

[T = double, A = allocator<double>, Dest = vector], 

與舊GCC-4.1.2相匹配,並與嶄新鐺 - 3.4 - 有和沒有-std=c++11標誌。

+0

我不能使用模板模板,因爲我必須支持的一些容器是非標準的,並且沒有相同的模板參數,或者不是模板。 –

+0

@JamesKanze爲什麼你不能繼續添加operator()定義來滿足所有可能的匹配? – mockinterface

+0

因爲我不知道所有可能的比賽。試圖這樣做或多或少地破壞了使用模板開始的目的。 (我已經用了很多這個成語,它針對三種或四種特定類型,在這種情況下,我爲每個類型手動重載,但這不是這種情況。) –

相關問題