2017-09-08 10 views
2

생성자에서 템플릿 차감을 허용하는 새로운 C++ 17 기능의 모든 제한 사항을 이해하는 데 어려움을 겪고 있습니다. 특히부분 특수화로 클래스 템플릿 인수 차감

,이 예는 제대로 컴파일합니다 :

struct B {}; 

template <typename T, typename = T> 
struct A { 
    A(T) {} 
}; 

int main() { 
    B b; 
    A a(b); // ok 
} 

이 하나가되지 않지만 :

struct B {}; 

template <typename T, typename = T> 
struct A; 

template <typename T> 
struct A<T> { 
    A(T) {} 
}; 

int main() { 
    B b; 
    A a(b); // error 
} 

이 두 번째 경우의 오류는 다음과 같습니다

main.cpp: In function ‘int main()’: 
main.cpp:17:14: error: class template argument deduction failed: 
     A a(b); 
      ^
main.cpp:17:14: error: no matching function for call to ‘A(B&)’ 
main.cpp:4:12: note: candidate: template<class T, class> A(A<T, <template-parameter-1-2> >)-> A<T, <template-parameter-1-2> > 
    struct A; 
      ^
main.cpp:4:12: note: template argument deduction/substitution failed: 
main.cpp:17:14: note: ‘B’ is not derived from ‘A<T, <template-parameter-1-2> >’ 
     A a(b); 
      ^

은 왜이다 사고?

답변

4

클래스 템플릿 인수 차감은 공제를 수행하기 위해 기본 클래스 템플릿의 생성자 만 고려합니다.

template <class T> A<T> __f(T); 

__f(b)의 결과는 A<B>, 우리 완료 : 첫 번째 예에서, 우리는 우리가 함수 템플릿을 합성 한 생성자를 가지고있다.

template <typename T, typename = T> 
struct A; 

그것은 어떤 생성자가 없습니다, 그래서 우리는 그들로부터 합성 할 기능 템플릿이 없습니다 :

그러나 두 번째 예에서

는 기본 클래스 템플릿은입니다. 그래서, (당신이 얻을 컴파일 오류가 복사 공제 가이드에 맞게 노력에 관한 것입니다) __f(b)에 대한 실행 가능한 있습니다 어느 것도

template <class T> A<T> __f(); 
template <class T> A<T> __f(A<T>); 

: 우리가 모두 함께 우리에게이 오버로드 세트를주는 hypothetical default constructorcopy deduction guide입니다 공제가 실패합니다. 이 성공하려면


, 당신은 공제 가이드를 작성해야 : A a(b)이 작동 할 수 있도록 할

template <class T> 
A(T) -> A<T>; 

합니다.