2012-01-23 1 views
1

원래 부스트에서 파생 된 템플릿 클래스 쌍에 boost :: share_ptr을 통합하려고했습니다. :: asio 예제를 찾았습니다. 하나의 클래스 내에서 그 클래스의 공유 :: ptr 인 타입을 정의 할 때. 다른 템플릿 기반 클래스에서 해당 형식을 참조 할 수없는 것처럼 보입니다. 코드에서 템플릿을 제거하면 모두 컴파일됩니다.템플릿으로 된 boost :: shared_ptr을 정의하는 것이 템플릿이 아닌 클래스의 boost :: shared_ptr와 다르게 동작하는 이유

이 컴파일되지 않습니다 :

#include <iostream> 
#include <boost/shared_ptr.hpp> 
#include <boost/enable_shared_from_this.hpp> 

using namespace std; 

template <typename TSomething1> 
class SomeTemplateT : public boost::enable_shared_from_this<SomeTemplateT<TSomething1> > 
{ 
public: 
    typedef boost::shared_ptr<SomeTemplateT<TSomething1> > Ptr; 

    static Ptr Create() 
    { 
     return Ptr(new SomeTemplateT<TSomething1>()); 
    } 

    SomeTemplateT() 
    { 
     cout << "SomeTemplateT created" << endl; 
    } 
}; 

template <typename TSomething> 
class OtherTemplateT 
{ 
public: 
    OtherTemplateT() 
    { 
     // COMPILATION ERROR HERE 
     SomeTemplateT<TSomething>::Ptr someTemplate = SomeTemplateT<TSomething>::Create(); 
    } 

private: 

}; 
위의 코드는 다음과 같은 컴파일 오류가 산출

:

class SomeTemplateT : public boost::enable_shared_from_this<SomeTemplateT> 
{ 
public: 
    typedef boost::shared_ptr<SomeTemplateT> Ptr; 

    static Ptr Create() 
    { 
     return Ptr(new SomeTemplateT()); 
    } 

    SomeTemplateT() 
    { 
     cout << "SomeTemplateT created" << endl; 
    } 
}; 

class OtherTemplateT 
{ 
public: 
    OtherTemplateT() 
    { 
     SomeTemplateT::Ptr someTemplate = SomeTemplateT::Create(); 
    } 

private: 

}; 
:

src\Templates\main.cpp: In constructor 'OtherTemplateT<TSomething>::OtherTemplateT()': 
src\comps\oamp\src\Templates\main.cpp:30: error: expected ';' before 'someTemplate' 

템플릿없이 거의 동일한 코드를 촬영 어려움없이 컴파일

플랫폼 정보 : MinGW에서 gcc4.4.0을 사용하고 있습니다. Windows XP (코드 : IDEs 차단).

내가 잘못 했나요?

편집

: 부스트 :: shared_ptr의를 모든 것이 잘 컴파일 : 은 내가 공유 PTR의 전체 선언으로의 PTR의 형식 정의의 사용을 대체하는 경우 언급하는 것을 잊었다.

또한 템플릿의 외부 코드에서 유형을 사용할 수 있습니다.

+2

가능한 중복 [어디서 왜가 "템플릿"과 "유형 이름"키워드를 넣어해야합니까?] (http://stackoverflow.com/questions/610245/where-and-why-do-do-do-do-have-the-template-and-typename- 키워드) –

답변

4

SomeTemplateT<TSomething>::Ptr이고 종속 이름은입니다. 즉, 해당 정의는 템플리트 매개 변수에 따라 다릅니다. 당신은 typename를 사용할 필요가

typename SomeTemplateT<TSomething>::Ptr someTemplate = SomeTemplateT<TSomething>::Create(); 
^^^^^^^^ 
+0

그랬습니다. 나는이 기괴한 오류가 발생할 때마다 typename :-)을 던지기를 기억해야합니다. – Lou

+1

@ 루 : 그 오류가 발생하면 실제로 예측할 수 있습니다. 형식의 이름에 템플릿 매개 변수가 있으면'typename'을 사용하십시오. –

3

:

typename SomeTemplateT<TSomething>::Ptr someTemplate = SomeTemplateT<TSomething>::Create(); 

이 의미 분석없이 가능한 구문 분석 할 필요가 당신이 그렇게 말하지 않는 한 컴파일러는 타입 이름이 있다고 가정 할 수 없다. SomeTemplateT<TSomething>::Ptr이 유형 또는 구성원인지 여부는 SomeTemplateT<TSomething>까지 컴파일됩니다.

1

키워드 이름이 (이 컨텍스트에서) 인 이유를 보여주는 C++ 11 Standard (n3290)에서 가져온 예제입니다. (14.6 이름 확인 [temp.res])의

struct A 
{ 
    struct X { }; 
    int X; 
}; 

struct B 
{ 
    struct X { }; 
}; 

template<class T> void f(T t) 
{ 
    typename T::X x; 
} 

void foo() 
{ 
    A a; 
    B b; 
    f(b); // OK: T::X refers to B::X 
    f(a); // error: T::X refers to the data member A::X not the struct A::X 
} 
관련 문제