C++ 获取继承的实例化模板的类型

C++ 获取继承的实例化模板的类型,c++,templates,C++,Templates,是否可以从变量中获取实例化模板的类型 struct A { enum E {A_, B, C}; }; struct B { enum E {X, Y, Z}; }; class BaseClass {}; template <typename T> class TemplateClass : public BaseClass {}; class AChild : public TemplateClass<A> {}; class BChild : public Te

是否可以从变量中获取实例化模板的类型

struct A { enum E {A_, B, C}; };
struct B { enum E {X, Y, Z}; };

class BaseClass {};
template <typename T> class TemplateClass : public BaseClass {};

class AChild : public TemplateClass<A> {};
class BChild : public TemplateClass<B> {};

template <typename T>
class WorkerClass
{
  static void do_stuff(const BaseClass& a) {}
};

int main(void)
{
  AChild a;
  //need to call WorkerClass<A::E>::do_stuff(a)
}
struct A{enum E{A,B,C};};
结构B{enum E{X,Y,Z};};
类基类{};
模板类TemplateClass:公共基类{};
类ACHID:公共模板类{};
类BChild:公共模板类{};
模板
阶级工人阶级
{
静态void do_stuff(const BaseClass&a){}
};
内部主(空)
{
阿基尔德a;
//需要调用WorkerClass::do_stuff(a)
}
您可以执行以下操作:

template <typename T>
void foo(TemplateClass<T>& c)
{
    WorkerClass<typename T::E>::do(c)
}
其他传统方法是在模板类中添加类型:

template <typename T> class TemplateClass : public BaseClass
{
    using type = T;
};
模板类TemplateClass:公共基类
{
使用类型=T;
};
所以你可以

WorkerClass<AChild::type::E>::do(a);
WorkerClass::do(a);
您可以执行以下操作:

template <typename T>
void foo(TemplateClass<T>& c)
{
    WorkerClass<typename T::E>::do(c)
}
其他传统方法是在模板类中添加类型:

template <typename T> class TemplateClass : public BaseClass
{
    using type = T;
};
模板类TemplateClass:公共基类
{
使用类型=T;
};
所以你可以

WorkerClass<AChild::type::E>::do(a);
WorkerClass::do(a);

C++具有RTTI(运行时类型标识)。也许您想使用
std::dynamic_cast
来实现此目的

dynamic_cast(elem)尝试从elem获取T类型的对象

  • 如果T的类型为pointer,则返回指向该对象的指针,或者返回0(如果 指向的对象不是类型T)
  • 如果T是reference类型,则返回对对象的引用,或者 引发std::bad_强制转换异常

C++具有RTTI(运行时类型识别)。也许您想使用
std::dynamic_cast
来实现此目的

dynamic_cast(elem)尝试从elem获取T类型的对象

  • 如果T的类型为pointer,则返回指向该对象的指针,或者返回0(如果 指向的对象不是类型T)
  • 如果T是reference类型,则返回对对象的引用,或者 引发std::bad_强制转换异常
是否可以从变量中获取实例化模板的类型

struct A { enum E {A_, B, C}; };
struct B { enum E {X, Y, Z}; };

class BaseClass {};
template <typename T> class TemplateClass : public BaseClass {};

class AChild : public TemplateClass<A> {};
class BChild : public TemplateClass<B> {};

template <typename T>
class WorkerClass
{
  static void do_stuff(const BaseClass& a) {}
};

int main(void)
{
  AChild a;
  //need to call WorkerClass<A::E>::do_stuff(a)
}

  • 更新类模板以提供用于实例化它的类型

    template <typename T> struct TemplateClass : public BaseClass
    {
       using type = T;
    };
    
    是否可以从变量中获取实例化模板的类型

    struct A { enum E {A_, B, C}; };
    struct B { enum E {X, Y, Z}; };
    
    class BaseClass {};
    template <typename T> class TemplateClass : public BaseClass {};
    
    class AChild : public TemplateClass<A> {};
    class BChild : public TemplateClass<B> {};
    
    template <typename T>
    class WorkerClass
    {
      static void do_stuff(const BaseClass& a) {}
    };
    
    int main(void)
    {
      AChild a;
      //need to call WorkerClass<A::E>::do_stuff(a)
    }
    

  • 更新类模板以提供用于实例化它的类型

    template <typename T> struct TemplateClass : public BaseClass
    {
       using type = T;
    };
    

    除了@Jarod42的答案之外,您还可以在C++11中编写一个类型trait:

    template <typename T>
    T& GetEnumOfImpl(TemplateClass<T>&);
    
    template <typename T>
    using GetEnumOf = typename std::decay_t<decltype(GetEnumOfImpl(std::declval<T&>()))>::E;
    
    ...
    
    AChild a;
    WorkerClass<GetEnumOf<AChild>>::do_stuff(a);
    
    模板
    T&GetEnumOfImpl(TemplateClass&);
    模板
    使用GetEnumOf=typename std::decation\u t::E;
    ...
    阿基尔德a;
    工人阶级:做事(a);
    
    除了@Jarod42的答案之外,您还可以在C++11中编写一个类型trait:

    template <typename T>
    T& GetEnumOfImpl(TemplateClass<T>&);
    
    template <typename T>
    using GetEnumOf = typename std::decay_t<decltype(GetEnumOfImpl(std::declval<T&>()))>::E;
    
    ...
    
    AChild a;
    WorkerClass<GetEnumOf<AChild>>::do_stuff(a);
    
    模板
    T&GetEnumOfImpl(TemplateClass&);
    模板
    使用GetEnumOf=typename std::decation\u t::E;
    ...
    阿基尔德a;
    工人阶级:做事(a);
    
    @是的,这是因为
    AChild
    不是类模板,而是类模板的实例化。我最终为类型添加了别名,这是最简单的解决方案。@是的,这是因为
    AChild
    不是类模板,而是类模板的实例化。我最终为类型添加了别名,这是最直接的解决办法。