2011-10-23 109 views
1

我不知道我是否做錯了什麼,或者如果這是一個編譯器錯誤。我正在使用帶有SP1的英特爾C++ Composer XE 2011 for Windows(或更新版本6,這是當前最新版本)。請參閱代碼中的註釋行。Variadic模板行事怪異

#include <tchar.h> 
#include <iostream> 
#include <conio.h> 

template <typename ...T> 
struct first_va_arg {}; 

template <typename T0, typename ...T_> 
struct first_va_arg<T0, T_...> { 
    typedef T0 type; 
}; 

template <typename ...T> 
inline first_va_arg<T...>::type getFirstArgTypeDefaultValue(const T& ...values) 
{ 
//Next line causes error: nontype "first_va_arg<T...>::type [with T=<T...>]" is not a type name 
    typedef first_va_arg<T...>::type FirstArgT; 
    return FirstArgT(); 
//It works correctly if you comment out the above two lines and uncomment the single line below 
    //return first_va_arg<T...>::type(); 
} 


int _tmain(int argc, _TCHAR* argv[]) 
{ 
    std::cout << getFirstArgTypeDefaultValue(5.67, 32) << std::endl; 
    _getch(); 
    return 0; 
} 

回答

3

既然你有從屬名稱,你需要說typename

template <typename ...T> inline typename first_va_arg<T...>::type getFirstArgTypeDefaultValue(const T& ...values) 
//        ^^^^^^^^ 
{ 
    typedef typename first_va_arg<T...>::type FirstArgT; 
    //.. 
} 

注意,你缺少的基本情況爲沒有參數。我可能會與部分特做掉,只是聲明作爲主模板:

template <typename T, typename...> struct first_va_arg { typedef T type; }; 

然後,當你說first_va_arg<>::type,你沒有得到一個「不存在名稱」錯誤,但潛在的更具意義「模板參數不匹配」。由你決定。或者,您可以只使用聲明主模板,但將其保留爲未定義。

+0

謝謝。我忘記了所有關於typename的原因,因爲Intel編譯器對這些的要求相當寬鬆。但是這次是typedef需要的。但是,您不需要爲函數返回類型添加typename(至少在此編譯器上)。 – zeroes00

+0

好吧,如果我們談論的是C++語言,那麼你必須添加它。如果我們談論你的編譯器及其擴展和細節,恐怕我不知道,因爲我不熟悉它。 –

+0

我認爲關於typename的寬鬆規則與C++ 11一起出現,但我可能是錯的。 – zeroes00