2017-09-14 1 views
6

"템플릿 클래스의 친구 템플릿 함수를 선언 외부에 정의하는 방법"(SO/cppreference)이 발견되었지만, 믹스에 내부 템플릿이 아닌 다른 클래스를 추가하는 방법은 무엇입니까?두 클래스 외부의 템플릿 클래스 내부의 비 템플릿 클래스에서 선언 된 friend 함수를 정의하는 방법은 무엇입니까?

e.e. (외부) operator<< 다음 예제에서 class Internal 선언을 정의하는 방법 :

#include <iostream> 

template <typename T> 
class External { 
public: 
    explicit External(T initial) : value{initial} {} 
    class Internal { 
    public: 
     Internal(const External& e) : internal_value{e.value} {} 

    private:   
     friend std::ostream& operator<<(std::ostream& os, const Internal& i); 
     // ^^^ this one 
     /* body 
     { 
      return os << i.internal_value; 
     } 
     */ 

     T internal_value; 
    }; 

    friend std::ostream& operator<<(std::ostream& os, const External& e) 
    { 
     return os << Internal{e}; 
    } 
private: 
    T value; 
}; 

int main() 
{ 
    std::cout << External<int>{5}; 
} 
+0

를하십시오 유지 보수 방식으로 그 작업을 수행하는 방법은 (템플릿 파라미터에 종속 된 ) 멤버 함수 위임 대신이 작업을하는 작업자 정의를 인라인 유지하는 @StoryTeller 조회 규칙은 무엇입니까? –

+0

@RichardHodges - 너도 알다시피, 나는 더 이상 확신하지 못한다. 내 조회 규칙을 혼동시킬 수 있습니다. ADL에서만 발견 할 수있는 OP의 인라인 기능입니다. – StoryTeller

+3

누가 이것을 너무 광범위하게 투표 했습니까 ...? –

답변

6

가 여기에 문제가 있습니다. 사실 External은 템플릿이고 Internal은 종속 형식입니다. friend 함수는 자체적으로 템플릿 화되지 않습니다. 이상하게 보일 수도 있지만 템플릿 매개 변수에 의존하지 않습니다.

인라인으로 정의하면 템플릿의 각 특수화도 관련 friend 기능을 만듭니다. 그러나 인라인이 아닌 경우 각 전문 분야에 대한 연산자 정의를 으로 명시 적으로 제공해야합니다. 그리고 함수는 템플릿이 아니기 때문에 템플릿으로는 그렇게 할 수 없습니다.

그래서 당신은 템플릿 선언 한 후이를 추가하는 경우 : 그것은 구축 할 것입니다

std::ostream& operator<<(std::ostream& os, External<int>::Internal const& i) 
{ 
    return os << i.internal_value; 
} 

. 보시다시피 함수에서만 구체적인 유형 만 사용됩니다.

분명히 그다지 해결책이 아닙니다. 분별있는 사람이라면 누구나 External의 전문화를 통해 친구 정의를 생성 할 수 있습니다.

class Internal { 
public: 
    Internal(const External& e) : internal_value{e.value} {} 

private: 
    std::ostream& print(std::ostream&) const; 
    friend std::ostream& operator<<(std::ostream& os, Internal const& i) 
    { 
     return i.print(os); // Short and sweet on account of being inline 
    } 

    T internal_value; 
}; 

//.... 

template<typename T> 
std::ostream& External<T>::Internal::print(std::ostream& os) const { 
    // Provided outside of the class definition, can be as verbose as you like 
    return os << internal_value; 
} 
+2

하하! 네가 나보다 먼저 대답 해 준 것 같아. 당신의 대답은 더 완전합니다. 내가 지울거야. –

관련 문제