C++ 通过typedef模板强制模板实例化<;类型名T,T>;-为什么有效?

C++ 通过typedef模板强制模板实例化<;类型名T,T>;-为什么有效?,c++,crtp,template-instantiation,C++,Crtp,Template Instantiation,我正在学习强制模板实例化。 它起作用了,但我还是很好奇:- #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 dum

我正在学习强制模板实例化。
它起作用了,但我还是很好奇:-

#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#
int-lala=0;
模板类InitCRTP{
公共:静态int init;
public:使用dummy=NonTypeParameter;//#2#
};
模板int InitCRTP::init=lala++;
类WantInit:public InitCRTP{
};
int main(){
标准::cout
为什么第2行足以强制实例化

为了提供第二个参数,编译器必须绑定一个引用。这意味着它ODR使用静态变量,因此该变量必须存在并具有唯一标识。因此,它的定义被实例化

使用纯
int
时,第二个参数只能接受整数常量表达式。非常量静态在常量表达式中不可用

为什么我需要
int&
作为另一个模板参数使其可编译

您需要为第二个参数声明引用的类型,以使其具有编译器可以检查的类型。在C++17之前,您仍然需要声明引用的类型。现在,我们可以使用占位符类型代替

template <auto&>struct NonTypeParameter { };//#1#
using dummy=NonTypeParameter<init>;//#2#
模板结构非类型参数{};//#1#
使用dummy=NonTypeParameter;//#2#

这将使ODR使用传入的静态,而不必显式指定引用类型。

谢谢。回答得好。您是否碰巧对奇怪的行为“Ergo,它的定义已实例化”有一些引用?谢谢,你在另一篇文章中引用的关于“让我安息”的话。@StoryTeller:你如何理解[temp.inst]的明显含义/2-3这样一个成员类型别名不应该被急切地实例化?@DavisHerring-我认为这是一个措辞问题。它不应该仅仅以任何方式暗示。而且我所在的阵营同意GCC和Clang的实现。应该确定它是否正确explicit@StoryTeller:对我来说,它似乎与CWG2335有关,因为se可以用于“根据需要”实例化这些东西。当然,可以使用使用类型别名的成员声明来强制“需要”部分。同时,您可能会感兴趣的是,基于肯定实例化的内容来查看。