以下引用来自 Addison Wesley 的 C++ 模板。有人可以用简单的英语/外行术语帮助我理解它的要点吗?
Because string literals are objects with internal linkage (two string literals with the same value but in different modules are different objects), you can't use them as template arguments either:
最佳答案
您的编译器最终会在名为 translation units, informally called source files 的东西上运行。 .在这些翻译单元中,您可以识别不同的实体:对象、函数等。链接器的工作是将这些单元连接在一起,而该过程的一部分是合并身份。
标识符有链接†:内部链接表示该翻译单元中命名的实体仅对该翻译单元可见,而< em>external links 表示实体对其他单位可见。
当一个实体被标记为static
时,它被赋予internal链接。所以给定这两个翻译单元:
// a.cpp
static void foo() { /* in a */ }
// b.cpp
static void foo() { /* in a */ }
每个 foo
都引用一个实体(在这种情况下是一个函数),该实体仅对其各自的翻译单元可见;也就是说,每个翻译单元都有自己的foo
。
这里有一个问题:字符串字面量与 static const char[..]
的类型相同。那就是:
// str.cpp
#include <iostream>
// this code:
void bar()
{
std::cout << "abc" << std::endl;
}
// is conceptually equivalent to:
static const char[4] __literal0 = {'a', 'b', 'c', 0};
void bar()
{
std::cout << __literal0 << std::endl;
}
如您所见,文字的值在该翻译单元内部。因此,例如,如果您在多个翻译单元中使用 "abc"
,它们最终都会成为不同的实体。‡
总的来说,这意味着这在概念上毫无意义:
template <const char* String>
struct baz {};
typedef baz<"abc"> incoherent;
因为 "abc"
对于每个翻译单元不同。每个翻译单元都会被赋予一个 不同的 类,因为每个 "abc"
都是不同的实体,即使它们提供了“相同”的参数。
在语言层面,这是通过说模板非类型参数可以是指向具有外部链接的实体的指针;也就是说,做的事情在翻译单元中引用同一个实体。
所以这很好:
// good.hpp
extern const char* my_string;
// good.cpp
const char* my_string = "any string";
// anything.cpp
typedef baz<my_string> coherent; // okay; all instantiations use the same entity
†并非所有标识符都有链接;有些没有,比如函数参数。
‡ 优化编译器会将相同的文字存储在同一地址,以节省空间;但这是实现细节的质量,而不是保证。
关于c++ - 字符串文字不允许作为非类型模板参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5547852/