2011-08-18 66 views
2

我通過一個簡單的可變參數模板功能已經been frustrated這兩個可變參數函數之間的本質區別是什麼?

constexpr size_t num_args() { 
    return 0; 
} 

template <typename H, typename... T> 
constexpr size_t num_args() { 
    return 1 + num_args <T...>(); 
} 

int main() { 
    std :: cout << num_args <int, int, int>(); 
} 

以上不編譯,見上面鏈接的細節問題and followup,但下面的函數編譯

template <typename T, typename... Args> void foo (T, Args...); 

template <typename... Args> void foo (int, Args...); 

void foo() {} 

template <typename... Args> 
void foo (int x, Args... args) 
{ 
    std :: cout << "int:" << x; 
    foo (args...); 
} 

template <typename T, typename... Args> 
void foo (T x, Args... args) 
{ 
    std :: cout << " T:" << x; 
    foo (args...); 
} 

foo (int (123), float (123)); // Prints "int:123 T:123.0" 

似乎都要使用相同的語言機制,但爲什麼第二個好的時候第一個不好呢?

+0

沒關係,那不是真的重複,抱歉。 –

+2

請注意'num_args'可以做爲sizeof ...(Args)'。 – GManNickG

+0

不錯的提示,GMan,謝謝,但是這段代碼是爲了演示可變參數的語法。 – spraff

回答

0

我開始認爲,不同的是,

foo (args...); 

漏洞過載而

num_args <T...>(); 

利用專業化。

重載可以處理基本情況,但專業化不能用於函數模板(但它可以用於類),這就是爲什麼auxilliary_class<Args...>::value是慣用的。

4

不同的是,第一個函數

constexpr size_t num_args() { 
    return 0; 
} 

不是一個模板,所以它可以永遠這樣調用

num_args <T...>(); 
相關問題