通过 typedef template<typename T, T> 强制模板实例化 - 为什么它有效?
Force template instantiation via typedef template<typename T, T> - why it works?
我正在学习强制模板实例化。
它有效,但我仍然很好奇:-
#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;
}
它打印 1,因为 InitCRTP<WantInit>::init
被正确实例化。
观察
- 如果我删除行
#2#
,它将打印 0。(InitCRTP<WantInit>::init
未实例化)。
如果我将 #2#
从 int&
更改为 int
,我将得到:-
error: the value of 'InitCRTP::init' is not usable in a constant
expression
如果我将 #1#
更改为 template <T>struct NonTypeParameter { };
并将 #2#
更改为 public: using dummy=NonTypeParameter<init>;
我将得到 :-
error: 'T' has not been declared
问题
为什么#2#
行就足以强制实例化了?
在我看来,它只是模板 class 中的一个 typedef ,任何人都无法访问。
为什么我需要 int&
作为另一个模板参数才能使其可编译?
一个可能更正确的问题:该技术的名称是什么?
原文post:Force explicit template instantiation with CRTP
Why the line #2# is enough to force instantiation?
为了提供第二个参数,编译器必须绑定一个引用。这意味着 ODR 使用静态变量,因此该变量必须存在并具有唯一标识。因此,它的定义被实例化了。
当你使用plain int
时,第二个参数只能接受整型常量表达式。非常量静态不能用于常量表达式。
Why do I need int&
as another template parameter to make it compilable?
您需要声明第二个参数的引用类型,以便编译器可以检查其类型。好吧,在 C++17 之前你无论如何都需要这样做。现在我们可以使用占位符类型来代替。
template <auto&>struct NonTypeParameter { };//#1#
using dummy=NonTypeParameter<init>;//#2#
这将 ODR 使用传入的静态而无需显式指定引用类型。
我正在学习强制模板实例化。
它有效,但我仍然很好奇:-
#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;
}
它打印 1,因为 InitCRTP<WantInit>::init
被正确实例化。
观察
- 如果我删除行
#2#
,它将打印 0。(InitCRTP<WantInit>::init
未实例化)。 如果我将
#2#
从int&
更改为int
,我将得到:-error: the value of 'InitCRTP::init' is not usable in a constant expression
如果我将
#1#
更改为template <T>struct NonTypeParameter { };
并将#2#
更改为public: using dummy=NonTypeParameter<init>;
我将得到 :-error: 'T' has not been declared
问题
为什么
#2#
行就足以强制实例化了?
在我看来,它只是模板 class 中的一个 typedef ,任何人都无法访问。为什么我需要
int&
作为另一个模板参数才能使其可编译?
一个可能更正确的问题:该技术的名称是什么?
原文post:Force explicit template instantiation with CRTP
Why the line #2# is enough to force instantiation?
为了提供第二个参数,编译器必须绑定一个引用。这意味着 ODR 使用静态变量,因此该变量必须存在并具有唯一标识。因此,它的定义被实例化了。
当你使用plain int
时,第二个参数只能接受整型常量表达式。非常量静态不能用于常量表达式。
Why do I need
int&
as another template parameter to make it compilable?
您需要声明第二个参数的引用类型,以便编译器可以检查其类型。好吧,在 C++17 之前你无论如何都需要这样做。现在我们可以使用占位符类型来代替。
template <auto&>struct NonTypeParameter { };//#1#
using dummy=NonTypeParameter<init>;//#2#
这将 ODR 使用传入的静态而无需显式指定引用类型。