2015-12-28 50 views
1

這裏是一個非常簡單的例子:C++模板,而無需使用「&」不能推斷引用類型

#include <iostream> 

template<typename T> 
void DoubleMe(T x) { 
    x += x; 
} 

int main() 
{ 
    int a = 10; 
    DoubleMe(a); 
    std::cout << a; //displays 10 not 20! 
} 

的情況下這樣的,我是被迫在函數的參數,而不是用「T &」?因爲我已經閱讀過一些教程,通過在變量前面定義一個簡單的'T',模板可以正確地推導出適當的數據類型,包括T *,T []或T &。幫幫我?

+5

編譯器如何可能推斷出您打算將參數作爲參考?你將如何編寫一個需要*非*參數參數的模板? (順便說一句,教程是錯誤的,投資一本書。) – molbdnilo

+1

@molbdnilo推薦C++書籍最好伴隨着[此鏈接](http://stackoverflow.com/q/388242/1782465)。 – Angew

+0

@molbdnilo感謝您的信息,真的很感激。但我告訴你,我閱讀的教程是高度評價的,因爲它是2011年10月份針對C++的最佳文章。這是它的確切引用:「模板參數類型T可以從T&,T *或T []」推斷出來。以下是可靠來源的鏈接:http://www.codeproject.com/Articles/257589/An-Idiots-Guide-to-Cplusplus-Templates-Part#PtrWithTempl – Loqz

回答

5

你確實可以正確地推斷參考類型與純T。不幸的是,這並不意味着你的想法。

鑑於

template <typename T> struct S { }; 
template <typename T> void f(S<T>) { } 
int main() { f(S<int&>{}); } 

f類型參數被正確地推導出int&

問題是,在你的情況下,推導出Tint已經產生了一個完全有效的函數。也許略微過分簡單化,但類型扣除產生使呼叫正常工作的最簡單的T。在你的情況下,T = int使呼叫工作。不是你希望它工作的方式,但編譯器不知道。 T = int &也可以使通話起作用,但它並不是最簡單的T,它使其工作。

6

是的,要獲得您想要的效果,您必須添加&符號。

在編寫時,模板可以正確推導出數據類型。但是,他們不能推斷意圖。在這種情況下,您傳遞給它的類型是一個整數,它正確地實例化了一個整數函數,該函數在內部將通過值傳遞給它的參數加倍。事實上,你的意思是有副作用的功能,這不是編譯器能夠猜到的。

+2

雖然這個答案當然是真的,但應該注意的是,即使'a'的類型實際上是'int&','T'仍然會被推斷爲'int'。不幸的是,我不認爲有一種正確和簡單的陳述C++類型演繹規則的方式。 – Angew

+0

@Angew謝謝你的觀點。 –

0

如果希望函數按值傳遞參數,則需要使用相同的參數類型返回值。

T DoubleMe(T x) { 
    return x + x; 
}