0

今天,有人向我展示了以下形式的代码:

#include <iostream>

namespace example {
    template <typename T>
    T variable_template = T(42);
}

int main() {
    example::variable_template<int> = 10;
    std::cout << example::variable_template<int> << std::endl;
}

你可以在这里看到它运行:http: //coliru.stacked-crooked.com/a/3a786c42b5204b0a

我预计此代码将打印 42,因为 10 似乎分配给了一个临时的。在命名空间内,模板只有一个声明(不是实例化),因此在命名空间内没有数据可以改变。尽管如此,它还是让我感到惊讶并打印了 10 个。

我本来也希望对临时分配的警告发出警告,但这也没有发生。

这是未定义的行为,是我对模板的理解有缺陷,还是发生了其他事情?

4

1 回答 1

4

在命名空间内,模板只有一个声明(不是实例化),因此在命名空间内没有数据可以改变。

不是这样!

[C++14: 14.7.2/6]:类、函数模板或变量模板特化的显式实例化放置在定义模板的命名空间中。[..]

当您有一个类 templateFoo并引用一个实例化(例如Foo<int>)时,该实例化就像一个普通类一样存在,具有与模板相同的范围。

变量模板没有什么不同。当您引用 时example::variable_template<int>,您将该变量“添加”到包含模板的范围内。

然后,您的命名空间example包含一个名为variable_template<int>.


我本来也希望对临时分配的警告发出警告,但这也没有发生。

这里没有临时工,除了T(42).

于 2017-01-08T02:41:34.183 回答