1

코드를 GCC에서 MSVC로 이식 할 때 발생하는이 애매한 문제에 직면했습니다.Visual Studio에서 <variadic template> 템플릿 매개 변수의 기본값이 컴파일 오류입니다.

template <typename T> 
struct Foo; 

template <template <typename...> typename Container, typename Arg> 
struct Foo<Container<Arg>> { 
    using arg_t = Arg; 
}; 

template <typename X> 
struct A {}; 

template <typename X, typename Y = void> 
struct B {}; 

template <typename X, typename Y = void, typename Z = void> 
struct C {}; 

int main() { 
    typename Foo<A<int>>::arg_t a; 
    typename Foo<B<int>>::arg_t b; 
    typename Foo<C<int>>::arg_t c; 
    return 0; 
} 

우리는 디폴트 값 (실제 사용 사례 예를 들어 std::unique_ptr 함께)이 두 번째 템플릿 매개 변수에서 시작하는 템플릿 클래스의 첫 번째 인수를 추출 Foo 특성을 사용

는 다음 코드를 생각해 보자. Clang과 GCC는이 스 니펫을 완벽하게 처리하지만 MSVC (Visual Studio 17에 포함 된 것)는 매우 복잡한 컴파일 오류를 발생시킵니다.

답변

1

GCC와 Clang이 어떻게 든 기본 템플릿 매개 변수를 처리하므로 A<X, Y=void><template <typename...> typename Bar, typename X> Bar<X> 인터페이스에 허용됩니다. 반면에 MSVC는 그렇지 않습니다. 표준 또는 GCC/Clang 확장인지 확실하지 않습니다. 어쨌든 해결책은 남은 매개 변수과 일치하는 더미 가변 매개 변수를 추가하는 것입니다.

template <typename T> 
struct Foo; 

template <template <typename...> typename Container, 
      typename Arg, typename... MsvcWorkaround> 
struct Foo<Container<Arg, MsvcWorkaround....>> { 
    using arg_t = Arg; 
}; 

template <typename X> 
struct A {}; 

template <typename X, typename Y = void> 
struct B {}; 

template <typename X, typename Y = void, typename Z = void> 
struct C {}; 

int main() { 
    typename Foo<A<int>>::arg_t a; 
    typename Foo<B<int>>::arg_t b; 
    typename Foo<C<int>>::arg_t c; 
    return 0; 
} 

는 그것은 컴파일러 오류의 문제를 이해하고 내가 내 공유하려는 그 이유는, 해결책을 구글 수없는 정말 열심히했다.

+0

두 가지주의 사항 :이 해결 방법은 기본 코드가 아닌 반면 기본 설정되지 않은 매개 변수가 두 개 이상인 클래스 템플릿 (예 :'std :: map ')을 허용하고 기본값이 아닌 클래스 템플릿을 허용하지 않습니다 형식이 틀린 반면 원본은 틀렸어. – oisyn

관련 문제