【发布时间】:2011-10-09 15:52:42
【问题描述】:
在CRTP to avoid dynamic polymorphism中,为了避免虚成员函数的开销,强加特定的接口,提出了如下方案:
template <class Derived>
struct base {
void foo() {
static_cast<Derived *>(this)->foo();
};
};
struct my_type : base<my_type> {
void foo() {}; // required to compile. < Don't see why
};
struct your_type : base<your_type> {
void foo() {}; // required to compile. < Don't see why
};
然而,派生类似乎不需要定义来编译,因为它继承了一个(代码编译良好,无需定义 my_type::foo)。实际上如果提供了一个函数,那么在使用派生类的时候就不会调用基函数了。
所以问题是,以下代码替换是否可以接受(和标准?):
template <class Derived>
struct base {
void foo() {
// Generate a meaningful error if called
(void)sizeof( Derived::foo_IS_MISSING );
};
};
struct my_type : base<my_type> {
void foo() {}; // required to compile.
};
struct your_type : base<your_type> {
void foo() {}; // required to compile.
};
int main() {
my_type my_obj;
my_obj.foo(); // will fail if foo missing in derived class
}
【问题讨论】:
-
什么编译器和版本?使用 g++ 4.2/4.6 进行的简单测试无需在派生类型中添加声明即可编译。您确定没有其他问题被您误解为与此相关吗?您是否复制了失败的确切代码? (顺便说一句,它编译的事实并不意味着它是有意义的,如果没有在派生类中实现
foo(),它将进入一个无限递归循环,如果尾递归优化是,它将以stackoverflow或无限循环结束执行。 -
哦,我差点忘了……为什么你认为你需要优化虚拟调度?你真的测量过性能吗?很有可能您无缘无故地使系统复杂化。在考虑优化之前,您应该测量并确保您有性能问题,并且它与那段代码有关,并且删除虚拟调度会改善......然后,再次测量,因为您可能仍然是错了。
-
由于您在
base<T>::foo()中(静态地)调用my_type::foo()和your_type::foo(),因此您必须声明这些成员函数似乎是明智的,否则您将有直接的无限递归。 -
这里的想法是帮助程序员定义一个“遵循”特定接口的派生类(通常是函子)。它不同于更常见的动态多态性用法。不过不确定这是个好主意。
标签: c++ templates virtual crtp