簡體   English   中英

可變列表與單個模板參數:標准說什么?

[英]variadic list vs single template parameter: what does the standard say?

請考慮以下代碼:

#include <iostream>
#include <type_traits>

// Variadic version
template<class... Variadic>
void f(const Variadic&... variadic)
{
    std::cout<<"variadic"<<std::endl;
}

// Single version
template<class Single, class = typename std::enable_if<std::is_fundamental<Single>::value>::type>
void f(const Single& single)
{
    std::cout<<"single"<<std::endl;
}

// Main
int main()
{
    f();              // variadic
    f(42);            // single : why?
    f(std::string()); // variadic 
    f(42, 42);        // variadic
    return 0;
}

我不明白為什么標記為“單一”的行編譯得很好(在g ++ 4.6.3下)並且不會產生重載解析問題。 c ++ 11標准是否說具有固定數量參數的模板函數優先於可能具有相同簽名的可變參數函數?

它真的 很簡單 (兩個實例,gcc和clang)

template<class...T> void foo(T&&...) {std::cout << "...T\n";}
template<class T> void foo(T&&) {std::cout << "T\n";}
int main() {
  foo(3);
}

重載沒有服用...似乎當選擇的是一個明確的模板參數是首選。

class=std::enable_if_t不會改變它。

所以你的函數f都是候選者,然后編譯器更喜歡沒有變量的函數。

14.8.2.4在部分排序期間推導模板參數[temp.deduct.partial]

/ 8:

如果A是從函數參數包轉換而P不是參數包,則類型推導失敗。 否則,使用得到的類型PA ,然后按照14.8.2.5描述進行14.8.2.5 如果P是函數參數包,則將參數模板的每個剩余參數類型的類型A與函數參數包的declarator-id的類型P進行比較。 每個比較都推導出函數參數包擴展的模板參數包中后續位置的模板參數。 如果對於給定類型的推導成功,則參數模板中的類型被認為至少與參數模板中的類型一樣專用。 [例如:

template<class... Args> void f(Args... args); // #1
template<class T1, class... Args> void f(T1 a1, Args... args); // #2
template<class T1, class T2> void f(T1 a1, T2 a2); // #3
f(); // calls #1
f(1, 2, 3); // calls #2
f(1, 2); // calls #3; non-variadic template #3 is more
// specialized than the variadic templates #1 and #

特別是f(1,2)例子。

當您將std::string作為T傳遞時,所有enable_if_t子句都會刪除單參數版本。

由於在“單個”版本中使用了第二個enable_if,template參數,因此編譯器將該版本視為更專用的模板,以便與啟用它的類型一起使用。
它被認為更專業,因為有些類型可以實例化可變參數模板,但“單個”不能。

一般規則是更專業的模板在重載決策中勝過不太專業的模板。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM