模板非类型参数?

时间:2014-06-17 19:11:41

标签: c++ templates

看看这段代码:

#include <string>
#include <iostream>
using namespace std;

template <typename T, const T& temp>
void g()
{
    cout << temp << endl;
}

static const std::string s = "abc";

int main() {
    g<string, s>();
}

当我用Visual C ++ 2013 11 CTP编译时,我得到:

“错误C2970:'g':模板参数'temp':'s':涉及具有内部链接的对象的表达式不能用作非类型参数”

但是,我在C ++ 14标准(14.3.2 [temp.arg.nontype])中阅读了以下内容:

“一个常量表达式(5.19),用于指定具有静态存储持续时间和外部或内部链接的完整对象的地址或”

我将此解释为“具有静态存储持续时间和外部链接的常量表达式”或“具有静态存储持续时间和内部链接的常量表达式”。 在我上面的例子中,变量不是“具有静态存储持续时间和内部链接的常量表达式”吗?

当我将s更改为:

std :: string s =“abc”;

然后它编译并且它可以工作,但这不符合标准,因为现在s不再是“常量表达式”。

有人可以对此有所了解吗? 我在这里误解了什么吗?

2 个答案:

答案 0 :(得分:11)

static替换为extern

extern const std::string s = "abc";

原因是在C ++ 98 / C ++ 03中,不允许使用内部链接的引用作为模板参数。

另请注意,只删除static ,如果const存在,则 工作,因为{{在命名空间级别声明的对象具有内部链接(除非它被声明为const)。因此,您需要使用extern,如上所示。

答案 1 :(得分:8)

在C ++ 98中,语言是(从14.3.2 / 1开始):the name of an object or function with external linkage...。允许内部链接的更改包含在C ++ 11中。

您的编译器可能只编译为C ++ 98(或03)标准,而不是C ++ 11。