[英]template programming: ambiguous call to overloaded function
我正在將排序算法作為個人培訓來實現(無需做作業!)。 我有以下代碼(不包括導入等):
template<class RandomIt, class Compare>
void sort(RandomIt first, RandomIt last, Compare comp)
{
/* actual sorting code is here */
}
template<class RandomIt>
void sort(RandomIt first, RandomIt last)
{
std::function<bool(decltype(*first), decltype(*last))> comp = [](decltype(*first) a, decltype(*last) b)
{
return a < b;
};
sort (first, last, comp);
}
嘗試通過測試數組調用此代碼
auto test_array_1 = std::make_unique <std::array < uint64_t,SORTING_TEST_LENGTH >> ();
std::copy(std::cbegin(*template_array), std::cend(*template_array), std::begin(*test_array_1));
sort(std::begin(*test_array_1), std::end(*test_array_1));
編譯器抱怨“對重載函數的歧義調用”(VC ++ C2668)。 從我的理解來看,這個電話應該不會模棱兩可。 同樣,給第二個排序函數中的調用一個第一個排序函數的模板參數沒有任何作用。
我在這里想念什么? 為何編譯器將第二個調用視為“模棱兩可”?
問題有兩個。
首先,通過ADL查找sort
,因此您將獲得兩個重載,並且它們都匹配。 通常,由於ADL可能引起歧義,因此當您不嘗試ADL重載時,命名功能與std
函數相同。
現在,僅當從namespace std;
傳遞類型時才會發生這種情況namespace std;
有時迭代器來自此名稱空間,但在這種情況下不是: array
使用原始指針迭代器。 ADL查找std::sort
的觸發器是std::function
。
這就引出了下一個問題:上面代碼中的std::function
帶來的收獲很少,而損失的很多。 將其替換為auto
。 將低級排序算法傳遞給可內聯的比較對象。
您仍然不希望將其稱為sort
。 如果調用它進行sort
,則需要使用名稱空間來限定調用,或(sort)
以阻止ADL。
ADL規則是考慮“重載”函數,以及參數名稱空間中的功能,參數指向的名稱空間,參數指向的名稱空間以及參數的模板參數等。 這是基於參數的查找或ADL或Koenig查找。 這意味着當使用另一個命名空間中的類型時,可能會發生某種類型的命名空間污染(這很可悲),但是這也會使一些不錯的事情發生(例如std :: cout <<“ hello world \\ n”;`)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.