2017-04-04 65 views
2

我有以下函數模板無效的轉換錯誤,返回值取決於它的泛型類型

template<typename T> 
T foo(){ 
    if(std::is_same<T,int>::value){ 
     return 1; 
    } 
    if(std::is_same<T,std::string>::value){ 
     return "Hello"; 
    } 
} 

我想這樣應用它:

int main(){ 
    std::cout << foo<int>() << std::endl; // 1 
    std::cout << foo<string>() << std::endl; // "Hello" 
} 

如果我嘗試編譯我的模板編譯器會拋出以下錯誤: error: cannot initialize return object of type 'int' with an lvalue of type 'const char [6]'

如果我刪除第二個if聲明一切編譯好,我得到正確的輸出,因此我猜對比std::is_same<T,int>::value按預期工作。

好像編譯器檢測的T的類型,如果檢查所有return語句匹配,並引發錯誤,因爲std::string是不是隱含強制轉換爲int

有沒有人有解決方案或其他解決方法來滿足我的意圖?

編輯

解釋我的意圖:我寫一個包裝類數據庫遊標類。由於通常定義了這些遊標,因此它有幾個成員函數,如getInt()getString()。我的想法是實現一個通用的get<T>(),它使用相應的遊標成員函數,這取決於T。在if語句

+0

在C++ 17你會如果constexpr允許某些零件不能編譯,請取得''。現在,代碼的所有部分必須對* all *可能的類型'T'有效。您將不得不添加該函數的單獨重載。 –

回答

1

當您引用foo<int>,編譯器生成就像從模板中包含以下功能:

int foo<int>(){ 
    if(true){ 
     return 1; 
    } 
    if(false){ 
     return "Hello"; 
    } 
} 

上面的代碼是病因爲(正如編譯器告訴你的),一個int不能用C字符串(char const [N])初始化。當然,相應的return聲明將永遠不會達到,但這是「死代碼消除」,這只是一個優化。

的解決方案「現在」中Dustin's answer所示,用C++ 17我們會得到if constexpr這是能夠放棄代碼路徑,你期望的方式:

template<typename T> 
T foo(){ 
    if constexpr (std::is_same<T,int>::value){ 
     return 1; 
    } 
    if constexpr (std::is_same<T,std::string>::value){ 
     return "Hello"; 
    } 
} 
2

忘記,充分專門的模板函數:

template<> 
int foo<int>(){ 
    return 1; 
} 

template<> 
std::string foo<std::string>(){ 
    return "Hello"; 
} 
+0

爲了幫助理解你的原始代碼爲什麼不起作用,用'int'替換原始模板中所有'T'的出現,這基本上是調用'foo ()'的結果。然後很明顯你有一個函數聲明返回一個'int'試圖返回一個'string'。 – Alain

+0

注意:它不是明確的實例化,而是模板專門化。 [見這裏](http://stackoverflow.com/a/4933205/1116364)。 –

+1

我應該說完全專門化...編輯。謝謝 –