我正在学习强制模板实例化。
它有效,但是我仍然很好奇:-
#include <iostream>
#include <string>
template <typename T, T>struct NonTypeParameter { };//#1#
int lala=0;
template <typename T> class InitCRTP{
public: static int init;
public: using dummy=NonTypeParameter<int&, init>; //#2#
};
template <typename T> int InitCRTP<T>::init = lala++;
class WantInit : public InitCRTP<WantInit>{
};
int main(){
std::cout << lala << std::endl;
}
因为InitCRTP<WantInit>::init
正确实例化,所以它打印1 。
观察
#2#
,它将打印0。(InitCRTP<WantInit>::init
未实例化)。如果#2#
从更改int&
为int
,我将得到:
错误:“ InitCRTP :: init”的值在常量表达式中不可用
如果我改变#1#
对template <T>struct NonTypeParameter { };
和#2#
对public: using dummy=NonTypeParameter<init>;
我会得到: -
错误:尚未声明“ T”
为什么该行#2#
足以强制实例化?
我认为,这只是模板类中的typedef ,任何人都无法访问。
为什么需要int&
另一个模板参数使其可编译?
一个可能更正确的问题:该技术的名称是什么?
原始文章:使用CRTP强制显式模板实例化
为什么#2#行足以强制实例化?
为了提供第二个参数,编译器必须绑定一个引用。这意味着ODR使用静态变量,因此该变量必须存在并具有唯一标识。因此,其定义被实例化。
当您使用plain时int
,第二个参数只能接受整数常量表达式。非常量静态在常量表达式中不可用。
为什么需要
int&
另一个模板参数使其可编译?
您需要声明第二个参数的引用类型,以使编译器可以检查该类型。好吧,在C ++ 17之前,您仍然需要。如今,我们可以改用占位符类型。
template <auto&>struct NonTypeParameter { };//#1#
using dummy=NonTypeParameter<init>;//#2#
这将ODR使用静态传递的内容,而不必显式指定引用类型。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句