通过typedef template <typename T,T>强制模板实例化-为什么有效?

javaLover

我正在学习强制模板实例化。
它有效,但是我仍然很好奇:-

#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

观察

  1. 如果我删除该行#2#,它将打印0。(InitCRTP<WantInit>::init未实例化)。
  2. 如果#2#更改int&int,我将得到:

    错误:“ InitCRTP :: init”的值在常量表达式中不可用

  3. 如果我改变#1#template <T>struct NonTypeParameter { };#2#public: using dummy=NonTypeParameter<init>;我会得到: -

    错误:尚未声明“ T”

  1. 为什么该行#2#足以强制实例化?
    我认为,这只是模板类的typedef ,任何人都无法访问。

  2. 为什么需要int&另一个模板参数使其可编译?
    一个可能更正确的问题:该技术的名称是什么?

原始文章:使用CRTP强制显式模板实例化

讲故事的人-Unslander Monica

为什么#2#行足以强制实例化?

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

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

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

您需要声明第二个参数的引用类型,以使编译器可以检查该类型。好吧,在C ++ 17之前,您仍然需要。如今,我们可以改用占位符类型。

template <auto&>struct NonTypeParameter { };//#1#
using dummy=NonTypeParameter<init>;//#2#

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

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

从具有typename的多个模板参数的template <typename T,T max,T min>结构继承

template<typename T, T> 是什么意思?

template <typename T>:仅允许使用静态数据成员模板

使用L = T(*)(T);在template <typename T>中的(*)是什么意思?

此模板语法“ typename = T”是什么意思?

typedef中的模板实例化是否具有有限的作用域?

模板<typename>模板<typename>是做什么的?

两次模板<typename T> 声明

模板<typename T = char>是否正确?

为什么在实现所有模板化类方法之前需要'template <class T>'

当使用debug_rep(&s)调用模板<typename T>字符串debug_rep(T * p)时,为什么T不是字符串*

template <template <typename> something_else>,这是什么?

为什么对于依赖类型,单词“ typedef”后面需要“ typename”?

为什么将struct与可变参数template参数一起使用会同时使两个模板实例化?

typedef和using会导致模板实例化吗?

C ++中的模板语法只是模板<typename T>吗?

typename std :: remove_reference <T>和constexpr typename std :: remove_reference <T>有什么区别?

为什么C ++模板实例化失败?

为什么以下代码导致模板实例化?

为什么“ for t [1] inererable”有效语法?

为什么扩展键T不是有效索引

使用template <typename>

模板参数列表中的额外typename关键字:有效吗?

C ++模板使用typename并将typedef传递给函数

为什么通过右值初始化非常量引用有效(在C ++ 11中)?

va_list仍在C ++中使用吗?还是鼓励使用template <typename ... T>?

“ T”不是参数“ T”的有效模板类型参数

[] <typename>(){}是否是有效的lambda定义?

模板实例化绑定在什么时候发生?