2015-08-07 2 views
0

Я хотел создать класс шаблона, который предоставил бы общие средства для класса, чтобы иметь член m_Type, который обозначает какой-то тип, предоставляемый наследующим классом. Рассмотрим это:CRTP с вложенным типом

template<typename T> 
struct TypeAttribute 
{ 
    T m_Type; 
}; 

template<typename T> 
struct TypeAttribute2 
{ 
    using Type = typename T::Type; 
    Type m_Type; 
}; 

struct Foo : TypeAttribute<Foo::Type> 
{ 
    enum class Type 
    { 
     Type1 
    }; 
}; 

struct Bar : TypeAttribute2<Bar> 
{ 
    enum class Type 
    { 
     Type1 
    }; 
}; 

Оба из них не из-за неполных типов (в первом случае Foo::Type и во втором Bar::Type), который является понятным. Я пропускаю что-то тривиальное или это просто неправильный подход, и я должен перемещать вложенные типы вне классов (я просто хотел, чтобы классы содержали соответствующие типы внутри себя, чтобы не заполнять более высокие пространства имен). Live demo here.

ответ

1

В то время, когда вы объявляете struct Foo и наследуете от TypeAttribute, Foo еще не является полным. То же самое для struct Bar.
Ваша проблема очень близка к этому post.

Возможно, это код, который я сделал может помочь вам Live Demo

#include <iostream> 
#include <string> 
#include <memory> 

enum class ChildType 
{ 
    Child1, 
    Child2 
}; 

template <typename Derived> 
struct Parent 
{ 
    void DisplayChildType() const 
    { 
     switch (Derived::type_) 
     { 
      case ChildType::Child1: std::cout << "Child1" << std::endl; break; 
      case ChildType::Child2: std::cout << "Child2" << std::endl; break; 
      default:; 
     } 
    } 
}; 

struct Child1 : Parent<Child1> 
{ 
    static constexpr ChildType type_ = ChildType::Child1; 
}; 

struct Child2 : Parent<Child2> 
{ 
    static constexpr ChildType type_ = ChildType::Child2; 
}; 

template <typename Type> 
void DisplayType(const Type& child) 
{ 
    const Parent<Type>* asParent = &child; 
    asParent->DisplayChildType(); 
} 

int main() 
{ 
    Child1 child1; 
    Child2 child2; 

    DisplayType(child1); 
    DisplayType(child2); 
} 
+0

Ну, как я уже говорил, я знал, что типы являются неполными - Я надеялся, что это может быть какой-то C++ 11 магии будет преодолеть это. Поэтому мне просто нужно перечислить перечисления в более широком диапазоне. –