2017-02-09 15 views
2
대 GCC

이 간단한 템플릿 특수화를 고려부분 템플릿 특수화 : MSVS

template<typename T, size_t I> 
struct S {}; 

template<typename T> 
struct S<T, std::tuple_size<T>::value> {}; 

는 템플릿 인수 std::tuple_size<T>::value에서 템플릿 매개 변수 T을 사용하기 때문에 GCC는 컴파일되지 않습니다

error: template argument 'std::tuple_size<_Tp>::value' involves template parameter(s)

이제 tuple_size 템플릿 인수에 typename std::remove_reference<T>::typeT을 교체하자

// Using primary structure template from previous example. 
template<typename T> 
struct S<T, std::tuple_size<typename std::remove_reference<T>::type>::value> {}; 

이 코드는 여전히 템플릿 인수에서 템플릿 매개 변수를 사용하지만 GCC는 오류나 경고없이이 매개 변수를 컴파일합니다. 왜?

non-type parameter of a partial specialization must be a simple identifier

이 이상한 제한은 무엇입니까 : 우리가 /std:c++latest 플래그 MSVS를 사용하여 두 번째 예제를 컴파일하려고하면

는 지금, 그것은 오류 C2755와 중지? I이 튜플 크기와 같아지면 컴파일 시간 재귀를 멈추고 싶습니다.

MSVS 또는 GCC는 누구입니까? GCC는이 모든 인스턴스와 잘 작동하는 동안 MSVS이, 심지어 어떤 템플릿 인스턴스화하지 않고 오류를보고하는

참고 :

S<std::tuple<int, float>, 9> s1; 
S<std::tuple<int, float>, 2> s2; 
S<int, 42> s3; 

내가 그것으로 MSVS 커뮤니티 2015 업데이트 3을 사용하여 기본 컴파일러와 GCC 6.2.1입니다.

Tried Clang 3.8.0. 그것은 GCC의 메시지와 유사한 오류가 두 조각을 컴파일되지 않습니다 :

error: non-type template argument depends on a template parameter of the partial specialization

답변

3

부분 클래스 템플릿 특수화의 생존을 다루는 표준의 특정 부분은 지난 몇 년 동안 시간이 많이 변경되었습니다. 원래 restrictionin는 [temp.class.spec.match] 읽기 :

A partially specialized non-type argument expression shall not involve a template parameter of the partial specialization except when the argument expression is a simple identifier.

코드는 분명히 충돌하여 그 실행 std::tuple_size<T>::value는 식별자가 아닙니다.

Each template-parameter shall appear at least once in the template-id outside a non-deduced context.

그러나 우리가 괜찮아 - T 첫 번째 템플릿 매개 변수로 비 추론 문맥에서 사용되는 :

그런 다음 읽기, cwg issue 1315 후, 변경. 그리고 template auto 후, 지금은 읽

If the template arguments of a partial specialization cannot be deduced because of the structure of its template-parameter-list and the template-id, the program is ill-formed.

그러나 우리는 너무가 괜찮아. 그것은 추론 할 수 있습니다, 당신은 올바른 "구조"를 가지고 있습니다 - 귀하의 전문성은 기본 템플릿과 동일한 위치에 비 형식 템플릿 매개 변수를 사용하고 있으며, 그것들은 잘 일치해야합니다.


나는 (내가 -C++ (14) 생각) 1315의 해상도를 다음과 같은 코드가 잘 형성해야한다고 생각하지만, GCC와 그 소리 모두를 거부합니다.불행한 수정하는 대신 두 유형을 매개 변수를 사용하는 것입니다 :

template <class T, class I> 
struct S; 

template<typename T> 
struct S<T, typename std::tuple_size<T>::type> {}; 

template <size_t I> 
using size_ = std::integral_constant<size_t, I>; 

int main() { 
    S<std::tuple<int>, size_<1>> s; 
} 

GCC와 그 소리는 모두가 하나를 받아들입니다.