2014-04-10 7 views
0

왜 컴파일러가 일치 항목을 찾을 수없고 자동으로 인스턴스화합니까?C++ 템플릿 클래스 유형 인스턴스화

template <typename T1, typename T2> 
struct A 
{ 
    A(const T1& t1_, const T2& t2_) 
    : t1(t1_), t2(t2_) 
    {} 

    T1 t1; 
    T2 t2; 
}; 

int main() 
{ 
    double d = 5.2; 
    std::string s("hi"); 
    A a(d, s); // this doesn't compile (gcc) 
    A<double, std::string> a1(d, s); // OK 
} 
GCC에서

컴파일 오류 : 오류 : 'A' 오류 전에 템플릿 인수 누락 : 예상 ';' before 'a'

답변

2

템플릿 매개 변수 차감은 함수 템플릿 호출에서만 발생합니다. 예제와 같은 것이 허용되면 여러 클래스 생성자, 다른 순서로, 다른 방식으로 템플릿 인수를 사용하는 생성자와 같은 복잡성을 추가 할 때 매우 혼란 스러울 것입니다. 이런 경우

, 우리는 종종 클래스 템플릿을 보완하기 위해 "확인"기능을 사용합니다 :

template <typename T1, typename T2> 
A<T1, T2> make_A(const T1& t1, const T2& t2) 
{ return A<T1, T2>(t1, t2); } 

int main() 
{ 
    double d = 5.2; 
    std::string s("hi"); 
    auto a = make_A(d, s); 
} 
+0

감사합니다. 하지만 왜 여러 클래스 생성자의 경우 혼란 스러울 지 모르겠다. 예를 들어, A가 클래스 B와 C에서 파생 된 경우, 여전히 중요하지 않습니다. 컴파일시 명시해야하는 유일한 변수는 명시 적으로 정의 된 변수 d와 s의 유형입니다. A (5.2, "hi")가 작동하지 않으면 이해할 수 있습니다. 그러나 d와 s의 유형은 이미 명시 적으로 정의되어 있습니다. – surfcode

+0

다중 클래스가 아닌 같은 클래스에있는 여러 생성자. – aschepler

-1

A 형의 객체, 즉 두 개의 인수를 가지고 있어야 것처럼 그것은 보인다 이중 표준 ::끈.

컴파일하지 않는 코드 행은 이러한 인수를 사용하지 않습니다.

1

매개 변수화 된 형식을 지정하지 않아 작동하지 않았습니다. 생각한 것일 수도 있지만 템플릿 매개 변수가 아닌 생성자 인수 만 지정하면됩니다. 동일한 생성자 인수이지만 템플릿 인수가 다른 struct A의 템플릿 특수 생성자가있을 수 있습니다.

확실히, 컴파일러는 고유 한 일치 항목을 찾으면 경고없이 유형을 추론하려하지만 컴파일러가이 생성자를 생성하는 순간을 기다리는 시간 폭탄이 아닐 수 있습니다. A< int, string >::A (double, string)?

사실, make_A() 기능을 제안하는 다른 대답도 문제를 요구하고 있다고 생각합니다. 어딘가에 코드를 묻어 두었다가 make_A(5,"whatever") 일 수 있습니다. 입력하지 않으려면 typedef 또는 using을 사용하지 않으시겠습니까? 난 항상 auto 읽는 데 더 많은 노력을 요구 찾았습니다.

+0

예, 상황에 따라 다릅니다. 그리고'std :: make_tuple','std :: make_shared','std :: make_unique' 등과 같은 것들에주의를 기울일 필요가 있습니다. 그러나 여전히 유용한 함수입니다. – aschepler

+0

@KevinZ - A :: A (double, string) - 시한 폭탄임을 동의했습니다. 이 경우 컴파일시 int에 double을 할당하면 문제가 될 수 있다는 컴파일 경고가 발생해야합니다. u가 int를 취하는 함수로 두 번 전달할 때처럼. 제가 말하는 건, 적어도 자동 유형 공제를하지 않기위한 돌처럼 보이지 않는 것 같아요. 함수, 템플릿 함수, 왜 생성자가 아닌가? – surfcode

+0

@surfcode :'A :: A (double, string)'은'int' 변수에'double' 값을 할당 할 사람이 없습니다. 사이에 계산이있을 수 있습니다. 유형이 'int'인 멤버가 없거나 다른 많은 가능성이 있습니다. 이 중 어느 것도 형식 공제에 차이를 만들 수 없습니다. – aschepler