C++11 推断'的类型名;这';在虚拟方法中 我知道C++中缺少反射和基本的模板力学,所以下面的例子不能工作。但也许有一种黑客可以通过另一种方式达到预期目的 template <typename OwnerClass> struct Template { OwnerClass *owner; }; struct Base { virtual void funct () { Template <decltype(*this)> temp; // ... } }; struct Derived : public Base { void whatever () { // supposed to infer this class and use Template<Derived> // any chance some macro or constexpr magic could help? funct(); } }; 模板 结构模板 { 所有者类*所有者; }; 结构基 { 虚空函数() { 模板温度; // ... } }; 结构派生:公共基 { 作废任何东西() { //应该推断出这个类并使用模板 //有没有可能一些宏或constexpr魔法能帮上忙? funct(); } };
在本例中,C++11 推断'的类型名;这';在虚拟方法中 我知道C++中缺少反射和基本的模板力学,所以下面的例子不能工作。但也许有一种黑客可以通过另一种方式达到预期目的 template <typename OwnerClass> struct Template { OwnerClass *owner; }; struct Base { virtual void funct () { Template <decltype(*this)> temp; // ... } }; struct Derived : public Base { void whatever () { // supposed to infer this class and use Template<Derived> // any chance some macro or constexpr magic could help? funct(); } }; 模板 结构模板 { 所有者类*所有者; }; 结构基 { 虚空函数() { 模板温度; // ... } }; 结构派生:公共基 { 作废任何东西() { //应该推断出这个类并使用模板 //有没有可能一些宏或constexpr魔法能帮上忙? funct(); } };,c++11,templates,C++11,Templates,在本例中,Derived::whatever()调用虚拟方法Base::funct(),并希望它将自己的类名(派生)传递给模板。编译器抱怨“'owner'声明为指向'Base&'类型引用的指针””。decltype(*this)不仅不提供类型名,而且提供引用,编译器也无法预先知道从派生调用了funct,这将要求将funct()作为模板 然而,如果funct()是一个模板,那么每个派生类都需要在每次调用中传递自己的名称,这是非常冗长和冗余的 有没有黑客绕过这个限制,调用funct()来推断调用类的
Derived::whatever()
调用虚拟方法Base::funct()
,并希望它将自己的类名(派生)传递给模板。编译器抱怨“'owner'声明为指向'Base&'类型引用的指针”
”。decltype(*this)
不仅不提供类型名,而且提供引用,编译器也无法预先知道从派生调用了funct,这将要求将funct()
作为模板
然而,如果funct()
是一个模板,那么每个派生类都需要在每次调用中传递自己的名称,这是非常冗长和冗余的
有没有黑客绕过这个限制,调用funct()来推断调用类的类型名?可能是
constepr
或macros
来帮助编译器推断正确的类型并减少派生类中的冗长?目前,这无法完成Base
是一个Base
,在实例化模板时没有其他内容。您试图将静态类型系统与运行前未解析的继承层次结构混合使用。同样的机制也是在对象的构造过程中不调用对象的virtual
成员函数的原因
在某种程度上,这种限制将来可能会改变。实现这一点的一个步骤是在中演示的。您应该使用CRTP模式(奇怪的重复模板模式)进行继承
定义基类:
struct CBase {
virtual ~CBase() {}
virtual void function() = 0;
};
定义一个准备好的CRTP类:
template<typename T>
struct CBaseCrtp : public CBase {
virtual ~CBaseCrtp() {}
void function() override {
using DerivedType = T;
//do stuff
}
};
模板
结构CBaseCrtp:公共CBase{
虚拟~CBaseCrtp(){}
void函数()重写{
使用DerivedType=T;
//做事
}
};
从CRTP one继承:
struct Derived : public CBaseCrtp<Derived> {
};
struct派生:公共CBaseCrtp{
};
它应该会起作用。了解派生类型的唯一方法是将其提供给基 它确实有效。感谢@enoc martinez,事实上,这是一个伟大的解决方案,只是如果有更多的类要从中派生,它会变得复杂。它似乎只适用于单一层次的继承。也许所需的行为可以封装在一个小的实用程序类中,并通过多重继承搁置一旁。