2013-10-07 4 views
0

문자열 -> 부울과 같은 암시 적 유형 변환을 허용하지 않음으로써 템플릿 클래스 매개 변수의 유형 검사를 수행하려고합니다. 이로 인해 컴파일 오류가 발생합니다. 다음 특정 시나리오는 간단한이다유형 검사 템플릿 클래스 매개 변수

#include <iostream> 
#include <string> 
using namespace std; 

template <class T> 
class myPair { 
T a, b; 
public: 
    myPair(T first, T second) { 
    a = first; 
    b = second; 
    } 
    void test(); 
}; 

typedef myPair<bool> boolParm; 

template<class T> 
void myPair<T>::test() { 
    if(a == true) { 
    cout << "a is true" << endl; 
    } else { 
    cout << "a is false" << endl; 
    } 
    if(b == true) { 
    cout << "b is true" << endl; 
    } else { 
    cout << "b is false" << endl; 
    } 
} 

int main() { 
    boolParm myObj(false, "false"); 
    myObj.test(); 
    return 0; 
} 

사용자가 실수로 2 개 가지 유형을 전달할 수 있기 때문에, 위의 시나리오의 출력은 바람직하지 않다 : BOOL 문자열 및 전달 이후 (거짓 올바른 처음 나타날 두 번째 것은 참일 것입니다 (문자열에서 부울로의 암시 적 유형 변환 이후 올바르지 않습니다). main()의 사용자 코드를 컴파일 오류가 발생하도록 제한하고 string/int 매개 변수를 생성자에서 전달하지 못하게하려고합니다. 그것은 bool 만 허용해야합니다. 오버로드 된 생성자 myPair (bool first, string second)를 사용하여 시도했지만 생성자가 호출되기 전에 string-> bool에서 암시 적 형식 변환이 발생했기 때문에 일치하지 않았습니다. 이 시나리오에서 템플릿 전문화를 사용하는 솔루션이 있습니까? 도움을 주시면 감사하겠습니다. 감사합니다.

답변

0

언뜻보기에는 이상한 행동입니다. 하지만 제가 말할 수있는 한, 당신은 그것을 금지 할 수 없습니다 - 어쨌든, bool과 같은 원시 타입이 아닙니다.

매개 변수의 암시 적 변환은 말을하기 전에 발생하며 char const *에서 bool으로의 암시 적 원시 형식 변환이있는 것으로 보입니다.

도 참조하십시오. 이 다른 질문 : Why does a quoted string match bool method signature before a std::string?

1

한 가지 해결 방법은 템플리트 된 팩토리 기능을 추가하여 myPair를 만드는 것입니다.

template <typename T> 
myPair<T> makeParam(T a, T b) { 
    return myPair<T>(a, b); 
} 

유형이 일치하지 않으면 모호한 템플리트 매개 변수 T로 컴파일에 실패합니다.

int main() { 
    boolParm myObj = makeParam(false, "false"); 
    myObj.test(); 
    return 0; 
} 

가 또는 생성자 변경 : 당신은 템플릿 전문화가 명시 적으로 같은 무언가를 볼 것이다 T.에 대한 귀하의 주요 기능을 특정 유형의 금지와이를 확장 할 수 있습니다

template <typename U, typename V> 
myPair(U a, V b); 

을 그리고 전문 필요한

이러한 전문 분야의 예 :

template <class T> 
class myPair { 
    T a, b; 
public: 
    template <typename U, typename V> // generic version 
    myPair(U first, V second) 
    { 
     // intentionally fail to compile 
     static_assert(false, "don't support generic types"); 
    } 

    template <> // template specialization 
    myPair(T first, T second) 
    { 
     // explicitly require exactly type T 
     a = first; 
     b = second; 
    } 
}; 
+0

여기 있기 때문에 그것은 매개 변수 변환 대신 실패하는 템플릿 해상도입니다! 영리한! – codeling

+0

의견을 주셔서 감사합니다 ... 내 문제는 main()의 부분이 사용자 코드이고 사용자에게 코드를 변경하거나 이미 작성한 사용자 코드를 위의 형식으로 지원하도록 요청할 수 없다는 것입니다. 이 기능을 구현하려면 기본 클래스 즉 myPair. –

+0

@gigaplex : 두 번째 옵션에서 언급 한 것과 같이이 시나리오에서 전문화를 사용하는 방법에 대해 좀 더 자세히 언급 할 수 있습니까? –

관련 문제