[英]Function templates - compiler choosing function with different parameter types when calling with the same type
我正在玩功能模板,我偶然發現了一個奇怪的互動。
template<class T1, class T2>
void foo(T1, T1);
template<class T1, class T2>
void foo(T1, T2);
//main
foo(1,1)
這調用foo(T1,T2),我不明白為什么。 那會怎么樣? 這些函數是否相互重載,為什么編譯器會選擇具有不同參數類型的函數?
Henri Menke的帖子的第一部分解釋了這種特殊的互動
在經歷了一些混亂后,我發現了一些更奇怪的東西
#include <iostream>
template<class T1, class T2>
void foo(T1 a, T1 b)
{
std::cout << "same\n";
}
template<class T1, class T2>
void foo(T1 a, T2 b)
{
std::cout << "different\n";
}
int main()
{
foo(1, 1);
foo<int, int>(1, 1);
}
在這段代碼中我得到了一個結果
different
different
但在評論出第一個電話之后
int main()
{
//foo(1, 1);
foo<int, int>(1, 1);
}
結果是
same
我正在使用VS2015,如果我在Ideone中寫同樣的東西( 比如這里 ),第一個的結果是
different
same
有人能夠解釋發生了什么(或不發生了什么)?
順便說一句,我得出的結論是調用foo<int, int>(1, 1);
應該是模棱兩可的。 兩個功能模板都具有相同的簽名,並且來自同一模板。 那是另一回事,他們為什么不碰撞呢?
通過簡單地刪除第二個模板,即擁有類似的源文件,很容易看出為什么會失敗
template<class T1, class T2>
void foo(T1, T1);
int main()
{
foo(1,1);
}
這在Clang中失敗了
test.cpp:6:3: error: no matching function for call to 'foo'
foo(1,1);
^~~
test.cpp:2:6: note: candidate template ignored: couldn't infer template argument
'T2'
void foo(T1, T1);
^
1 error generated.
編譯器無法推導出第二個模板參數T2
。
如果從第一個模板中刪除多余的T2
並使用此類源文件
template<class T1>
void foo(T1, T1);
template<class T1, class T2>
void foo(T1, T2);
int main()
{
foo(1,1);
}
編譯器將始終選擇第一個選項(如果T1
和T2
當然是相同的),因為它更專業。
另一種選擇是給T2
一個默認值。 然后第一個變體也可以從foo(1,1)
實例化。
template<class T1, class T2 = void>
void foo(T1, T1);
另一個有趣的事情是:
#include <iostream>
template<class T1, class T2>
void foo(T1, T1)
{ std::cout << "First choice!\n"; }
template<class T1, class T2>
void foo(T1, T2)
{ std::cout << "Second choice!\n"; }
int main()
{
foo<int,int>(1,1);
}
這將在運行時輸出:
First choice!
我不完全確定,但我相信這是因為在演繹的情況下(即使這里沒有執行),對於第一個變體,編譯器必須只推導出一種類型而不是兩種類型,這使得它更多專業選擇。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.