2011-10-23 3 views
1

내가 뭔가 잘못하고 있는지, 아니면 컴파일러 버그인지 궁금합니다. 저는 Intel C++ Composer XE 2011을 Windows 용 SP1 (또는 최신 업데이트 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에 대해 모두 잊어 버렸다. 그러나 이번에는 typedef에 필요했습니다. 그러나 함수 반환 유형에 typename을 추가 할 필요는 없습니다 (최소한이 컴파일러에서). – zeroes00

+0

글쎄, 만약 우리가 C++에 대해 말한다면, 당신은 그것을 추가해야만한다. 우리가 컴파일러와 확장 기능 및 세부 사항에 대해 이야기하고 있다면, 내가 잘 모르는 것처럼 나는 두려워합니다. –

+0

나는 typename에 관한 편안한 규칙이 C++ 11과 함께 왔다고 생각했지만 잘못된 것일 수 있습니다. – zeroes00