c++ - 通过示例了解变量模板

标签 c++ templates c++14

我试图通过以下示例了解变量模板的工作原理:

#include <iostream>

template <class T, const T& t>
int var = t.a;

struct T
{
    int a;
    constexpr T(): a(31){ }
};

T y;

const T t = y;

const T tt = T();

int main()
{ 
    std::cout << "var <T, t> = " << var<T, t> << std::endl;  //0
    std::cout << "y.a = " << y.a << std::endl;  //31
    std::cout <<"var <T, tt> = " << var<T, tt> << std::endl; //31
}

DEMO

老实说,我真的不知道这种行为。让我感到困惑的是特化 var<T, t>为 0,但 y.a31 .另外,如果我们初始化 T 类型的对象与临时我们也有不同的结果。你能澄清一下吗?

我的意思是,我正在寻找工作草案中的规范引用 N4296 ,描述该行为。

最佳答案

目前,变量模板的指定程度相当低。如果我们通过 the current core issues list ,我们看到了

过去也不清楚初始化顺序变量模板遵循什么。 CWG issue 1744修改 [basic.start.init]/p2 以澄清这一点

Dynamic initialization of a non-local variable with static storage duration is unordered if the variable is an implicitly or explicitly instantiated specialization, and otherwise is ordered [Note: an explicitly specialized static data member or variable template specialization has ordered initialization. —end note].

var<T, t>是具有静态存储持续时间的非局部变量,是隐式实例化的特化。因此它的动态初始化是无序的。从 t不符合常量初始化的条件,这意味着 var<T, t>可能在t的动态初始化之前初始化, 结果为 0,无论 var 之间的相对顺序如何的定义和t的定义,并且无论 var<T, t> 的实例化点如何.

因此,moving the definition of var below the definition of t 和/或 an explicit instantiation of var<T, t> 对正在打印的内容没有影响,而 providing an explicit specialization for var<T, t> still initializing it to t.a 导致第一行打印 31 .

关于c++ - 通过示例了解变量模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28415414/

相关文章:

c++ - 为什么我可以使用 std 命名空间中的名称,即使我是 "using namespace std;"?

jquery - 未捕获的 TypeError : $(. ..).responsiveSlides 不是函数

c++ - U+ 究竟代表什么?为什么我不能在我的 C++ 应用程序中创建一个 Unicode 中间字符串表?

c++ - 深度复制到堆上的 c 数组 block

c++ - verse_iterator 的 != 运算符不明确

c++ - 你能 static_assert 一个元组只有一种类型满足特定条件吗?

java - Velocity模板和里面的java代码

c++ - 为什么不能使用 'enable_if' 在此处禁用此声明

c++ - 泛型 lambda 的实例化

c++ - 在一个普通的可复制结构中, move 语义应该被实现吗?