2016-09-10 5 views
1

필자는 몇 가지 노트를 쓰고 있는데 컴파일을 위해서 으로 ostream에 대해 operator<< 오버로드 된 함수를 추가했습니다. 그것은 잘 컴파일하지만 <>template 인 내에서 class type으로 연산자를 오버로드하고 오버로드 된 함수의 두 번째 입력으로 해당 유형을 전달 했으므로 앞으로 정의 할 모든 클래스에 new 연산자를 사용하지 않겠습니까? 여기 내 참조 용 코드가 있습니다. 메모 용도로만 사용되며 기능이 없습니다. 이 SFINAE에 관해서연산자를 템플릿으로 오버로드하면 어떻게됩니까?

template <class type> 
ostream& operator<< (ostream& s, type x){ 
    s << x.getsmth(); 
    //... 
} 
+0

* "그것이 내가 지금부터 정의하는 모든 클래스에 대한 새로운 연산자를 사용하지 않습니다? "* 네, 근본적으로 그렇습니다. 그래서 템플릿 기반의 과부하를 추가하는 것이 현명하지 못한 이유입니다. –

+0

물론 거기에서 호출 된 메소드를 찾지 못하면 컴파일러는 미친 듯이 불평 할 것입니다. 그것이 내가 생각했던 거죠. –

+0

EVERY 클래스가 아닌 다른 클래스가 더 적합합니다 (예 : 클래스에만 해당). 정의한 템플릿과 동일한 네임 스페이스에 있습니다 ([ADL] (http : // en .cppreference.com/w/cpp/language/adl) 규칙). –

답변

0

는 나 자신 초보자 해요,하지만 당신이 올바른지처럼,이 템플릿은 몸이 컴파일되지 않는 경우에도, getsmth()을 제공하지 않습니다 클래스에 사용됩니다 보인다. 당신은 비록 SFINAE와이를 방지 할 수 있습니다이 예상대로 작동하는 것 같다 :

template <class T, typename = decltype(T().getSomething())> 
std::ostream& operator<< (std::ostream& s, T& x){ 
    s << x.getSomething(); 
    return s; 
} 

데모 : http://cpp.sh/8fyk

+0

그래, 너는 그걸 실제로 할 수 있었어.하지만 요점은 뭐니? 클래스 안에 정의하면 문제가 해결됩니다. 다른 일을 할 수 있다고 생각합니다. 클래스 외부의 메서드를 정의한 다음 원하는 클래스의 첫 번째 줄 뒤에'friend'를 추가하십시오. 그것은 자식 클래스가있는 클래스에서만 작동합니다. –

+0

이 예제는 멤버 함수'getSomething'이 정의 된 모든 클래스에서 작동합니다. 그것은 외부 코드에서 오는 클래스들과 함께 작동 할 것이고 특정 계층에서 클래스들을 묶지 않을 것입니다. 어떤 클래스에도'print' 함수를 추가하고이 함수를 작동 시키려면 유용 할 것입니다. –

관련 문제