具有指针数据类型的非类型函数模板参数

时间:2013-12-07 18:00:20

标签: c++

我正在使用模板概念学习c ++中的元编程。

我有以下问题。

我明白了什么?

1)INTEGER可用作非类型模板参数。

template <typename T, int VALUE>
T addBoth(T const & a)
{
   return VALUE + a;
}

我理解上述概念。

我不明白的是什么?

2)

template <typename T, char *name>
class Test .....


Test<10, "StackOverflow"> sTest;

Reason: String literals are objects with internal linkage. 

我不明白上面的第二点。

有人可以详细说明吗?

1 个答案:

答案 0 :(得分:2)

所以这个question应该包含您需要的所有信息,但这里有一个摘要。

OP文本中使用的引用:

  

因为字符串文字是具有内部链接的对象(两个字符串   具有相同值但在不同模块中的文字是不同的   对象),你也不能将它们用作模板参数。

所以Tony解释了为什么你不能这样做。

代码示例:

#include <iostream>

template <const char* P> void f() { std::cout << P << '\n'; }

int main() {
    f<"hello there">();
}

推理:

  

...因为“你好那里”并非100%保证解决单身   可用于实例化模板一次的整数值   (尽管大多数好的连接器会试图折叠所有用法   链接对象并生成一个具有单个副本的新对象   字符串)。

Mikael详细说明:

  

显然,像“foobar”这样的字符串文字不像其他文字   内置类型(如int或float)。他们需要一个地址   (const char *)。地址实际上是常量值   编译器替代文字出现的位置。那   地址指向某个地方,在编译时固定,在程序中   存储器中。

     

因此必须具有内部联系。内部联系   只是意味着不能跨翻译单位链接(编译   cpp文件)。编译器可以尝试这样做,但不是必需的。   换句话说,内部联系意味着如果你拿了地址   两个相同的文字字符串(即const char *的值)   转换为)在不同的cpp文件中,它们不会相同,在   一般

     

您不能将它们用作模板参数,因为它们需要一个   strcmp()检查它们是否相同。如果您使用了==,那么   只会比较地址,这些地址不一样   模板使用相同的文字字符串进行实例化   翻译单位。

     

其他更简单的内置类型,如文字,也是内部链接   (他们没有标识符,也无法链接在一起   不同的翻译单位)。然而,他们的比较是微不足道的   这是有价值的。所以它们可以用于模板。