문제

헤드에 정의 된 수업이 있습니다.

template <typename T> class MyClass
{
   template <typename U> friend std::ostream& operator<<(std::ostream& output, const MyClass<U>& p);
   public:
      ...
}

구현 파일에는 다음과 같습니다.

template <typename U> std::ostream& operator<<(std::ostream& output, const MyClass<U>& m)
{
   output << "Some stuff";
   return output;
}

모든 것이 정결하게 보입니다. 그러나이 연산자 (예 : std :: cout << myclass ())를 사용하려고 할 때 다음 링커 오류가 발생합니다.

Undefined symbols: std::basic_ostream<char, std::char_traits<char> >& operator<< <InnerType>(std::basic_ostream<char, std::char_traits<char> >&, MyClass<InnerType> const&)

나는 컴파일러가 나를 위해 이것을 자동으로 생성하지 않았다는 것이 놀랍습니다 ... 내가 무엇을 잘못하고 있는지에 대한 제안이 있습니까?

도움이 되었습니까?

해결책

구현 파일에는 다음과 같습니다.

그게 바로 문제 야. 헤더와 구현 파일 사이에 템플릿 정의를 분할 할 수 없습니다. 템플릿의 특성으로 인해 C ++ 컴파일러는 여기에서 까다 롭습니다. 헤더의 모든 코드를 정의하여 작동하도록합니다.

실제로, 여기서 문제는 C ++ 표준이 다른 단위에서 템플릿 정보가 공유되는 방식을 정의하지 않기 때문에 모든 템플릿 정의가 동일한 컴파일 장치 내에 있어야한다는 것입니다. 이 장치는 링커에 의해 함께 스티치되지만 제네릭은 컴파일 타임 (이전)에 해결됩니다. ~ 아니다 링크 시간에.

이론적으로 C ++ 표준은 키워드를 정의하고 export, 이러한 사례를 처리합니다. 실제로, 아니요 컴파일러는 이것을 구현하고 (한 가지 예외로), 비용/유용성 트레이드 오프가 충분히 좋지 않기 때문에 이것을 변경하려는 의도는 없습니다.

다른 팁

너무 많은 템플릿 - 이것은 작동합니다.

#include <iostream>
using namespace std;
template <typename T> struct MyClass {

    friend ostream & operator << ( ostream & os, MyClass<T> & c ) {
        os << "MyClass\n";
        return os;
    }
};

int main() {
    MyClass <int> c;
    cout << c;
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top