2017-12-13 4 views
0

Base 클래스 객체 포인터를 사용하여 외부 비 멤버 템플릿 함수 (DoSomething)에 템플릿 클래스 인스턴스 유형 별칭 (ClassTmplt/DerivedFloat::InternalType)을 전달하는 방법이 있습니까 (마지막 두 개는 test() 함수 주석 행)?템플릿 클래스 인스턴스 유형 별칭을 비 멤버 템플릿 함수에 전달

class Base 
{ 
}; 

template <typename T> 
class ClassTmplt: 
    public Base 
{ 
public: 
    using InternalType = T; 
}; 

class DerivedFloat: 
    public ClassTmplt<float> 
{ 
}; 

template <typename T, typename TIn> 
void DoSomething(const TIn value) 
{ 
    T val = T(value); 
    std::cout << val << " | " << typeid(val).name() << " | " << typeid(value).name() << std::endl; 
} 

template <typename T> 
typename T::InternalType PassInternalType(T* obj) 
{ 
    return T::InternalType; 
    //return obj::InternalType 
} 


void test() 
{ 
    Base* obj = new DerivedFloat; 
    DoSomething<float>(1.23); 
    DoSomething<DerivedFloat::InternalType>(1UL); 
    //DoSomething<(*obj)::InternalType>(-123); 
    //DoSomething<PassInternalType(obj)>(4.56); 
} 

답변

2

번호는 고려 : 포인터의 동적 유형은 런타임에 알고 있기 때문에 기능을 컴파일 할 때 컴파일러가에 액세스 할

void f(Base* ptr) { 
    // What type does ptr point to? 
    // The runtime derived type might not exist when this function compiles 
} 

, 그것은 불가능합니다.

정의가 유용 할 수 있지만 더 많은 옵션이있을 수 있지만 지원하려는 유형 집합 전체를 사전에 알고 필요하면 먼저 다운 캐스트해야 할 수도 있습니다.

방문객 패턴이있는 일부 제한된 디자인을 만들 수 있습니다.

+0

감사합니다. 다운 캐스팅의 의미 - 기본 클래스의 ID- 필드가 아닌 다른 클래스의 각 클래스에 대해 고유 한 ID가있는 것? 나는 그런 필드를 가지고 있지만 constexpr을 만들 수 없기 때문에 DoSomething에 사용할이 ID 필드에 의해 특수화 된 템플릿을 만들지 못했습니다 ... – g2mk

+0

파생 클래스가 형식을 노출하면 액세스 할 수 없습니다. 기본 유형 만 알면됩니다. 이것이 사람들이 CRTP를 사용하는 이유입니다 - Curiously Recurring Template Pattern. 기본은 템플리트이며 매개 변수는 기본 클래스가 사용할 수 있도록 파생 된 클래스 유형입니다. –

+0

아아 ... 왜 템플릿 기본 클래스에 대해 생각하지 못했습니다 : | CPTR에 감사드립니다. – g2mk

관련 문제