[英]C++ function template: Must use & for argument type and return type?
我正在學習使用功能模板。 我發現,如果我將參數類型聲明為引用,則程序將運行。 但是,如果參數類型不是引用,則會出錯。 例如:
下面的代碼打印正確的結果,並且沒有錯誤。
#include <iostream>
using namespace std;
template <typename T>
T & max (T & a, T & b){
return a>b?a:b;
}
int main(int argc, char const *argv[])
{
cout << max(1,2) << endl;
return 0;
}
但是,如果我刪除了代碼中的所有“ &
”,即如下更改上述程序:
#include <iostream>
using namespace std;
template <typename T>
T max (T a, T b){
return a>b?a:b;
}
int main(int argc, char const *argv[])
{
cout << max(1,2) << endl;
return 0;
}
此代碼將導致以下錯誤。
a.cpp: In function ‘int main(int, const char**)’:
a.cpp:11:17: error: call of overloaded ‘max(int, int)’ is ambiguous
cout << max(1,2) << endl;
^
a.cpp:5:4: note: candidate: T max(T, T) [with T = int]
T max (T a, T b){
^~~
In file included from /usr/include/c++/7/bits/char_traits.h:39:0,
from /usr/include/c++/7/ios:40,
from /usr/include/c++/7/ostream:38,
from /usr/include/c++/7/iostream:39,
from a.cpp:1:
/usr/include/c++/7/bits/stl_algobase.h:219:5: note: candidate: constexpr const _Tp& std::max(const _Tp&, const _Tp&) [with _Tp = int]
max(const _Tp& __a, const _Tp& __b)
為什么? 謝謝大家的幫助!
在第一個示例中不考慮引用參數版本,因為這些常量不適合可修改的左值引用。 還要感謝using namespace std;
的不當建議using namespace std;
,您可以改用std
版,它將起作用。 您可以在第一個版本中刪除您的max
代碼,並且該代碼仍然可以使用,因為一旦這些引用觸發取消資格,就不會考慮該代碼。
總之,第一個版本不考慮你的max
的代碼,因為它不符合,那么std::max
來代替(這不符合資格)。 在第二個版本中,使用值參數的代碼和使用const-references的std::max
版本都可以使用,因此結果含糊不清。
在std名稱空間中已定義具有相同(或兼容)名稱和參數類型的函數(模板)。
去掉
using namespace std;
並在cout和endl前面加上std :::
std::cout << max(1,2) << std::endl;
否則,您將用std名稱空間中的所有名稱污染全局名稱空間。
有一個模板化的max()
函數可以接受名稱空間std
參數(在標准標頭<algorithm>
)。 盡管該標准不要求#include <iostream>
引入該功能,但也不禁止該功能。 您的標准編譯器確實通過<iostream>
對其進行了介紹。
using指令( using namespace std
)使std::max()
模板被視為代碼中匹配函數的候選對象。
在您的第一個代碼示例中,調用max(1,2)
與std::max()
相匹配,因為它接受const
引用,並且比接受非const
引用的函數更好。 它恰好產生您期望的輸出。
在您的第二個代碼示例中,按值傳遞,編譯器沒有理由偏愛您的max()
或std
的一個(按值傳遞或按const
引用傳遞對於傳遞像1
或2
這樣的int
常量都同樣有效) 。 因此,編譯器抱怨模棱兩可。
問題在於:使用不同的編譯器(或其標准庫),您的代碼可能會以不同的方式失敗,因為不需要<iostream>
聲明std::max()
,並且並非所有實現都可以。
刪除using指令,您的代碼中std::max()
的潛在用法將消失-在任何一個代碼示例中, std::max()
都不會被視為候選。 您的第一個示例將無法編譯,因為不能使用非const
引用來傳遞文字值。 第二個將編譯並產生您期望的輸出。 在符合標准的C ++編譯器之間,此行為將是一致的(並且不影響諸如<iostream>
類的標准頭文件是否聲明std::max()
)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.