我已经通读this advice about template parameter constraints,并通过这条线困惑:模板参数约束
template<class T> class Container : Derived_from<T,Mybase> {
// ...
};
这是怎么回事?这只是简单的旧的继承被用来使编译器检查Derived_from
执行所需的检查?为什么这不会导致为Derived_from
生成代码?
谢谢。
我已经通读this advice about template parameter constraints,并通过这条线困惑:模板参数约束
template<class T> class Container : Derived_from<T,Mybase> {
// ...
};
这是怎么回事?这只是简单的旧的继承被用来使编译器检查Derived_from
执行所需的检查?为什么这不会导致为Derived_from
生成代码?
谢谢。
只要看看Derived_from
的源代码,它与您指向的URL完全相同!
template<class T, class B> struct Derived_from {
static void constraints(T* p) { B* pb = p; }
Derived_from() { void(*p)(T*) = constraints; }
};
你所期望的代码生成,除了在的Derived_from
构造函数初始化单这应该(一个希望)是容易的编译器优化掉?而且静态方法只是检查指向T
的指针是否可以正确指定给指向B
的指针 - 当然这应该变成纯编译时检查,即T
实际上是从B
导出的,这是我们所期望的约束。
如果执行这些检查的函数仅执行那些没有任何副作用的转换,那么优化器可能会优化整个代码,并且不会为函数体生成任何代码。剩下的唯一东西就是函数符号和返回指令。
事实证明(使用GCC 4.5.1进行测试),甚至不需要发射函数的符号。编译器优化了地址获取,然后观察该文件中没有其他代码访问该函数,而不是为其发送代码。我认为这是可以的,因为任何需要该定义的翻译单元本身都会提供一个定义 - 所以它们不依赖于其他翻译单元的编译。
请注意,使用此方法时,检查仅在您创建对象Container<T>
后触发。否则,Derived_from
的构造函数将永远不会被隐式实例化,并且检查从不完成。
有很多方法可以完全避免这种虚拟代码,如boost::is_base_of
。