这是一个很好的问题,因为它很难证明。我们可以利用C++标准中的其他规则来显示匿名名称空间中的变量可以具有外部链接。
在带有外部链接的int *上进行模板化将会成功,而对具有内部链接的int *进行模板化将失败。
#include <iostream>
namespace {
// not externally linked, won't compile
// const int i = 5;
// external linkage, compiles
extern int i;
int i = 5;
}
template<int* int_ptr>
struct temp_on_extern_linked_int {
temp_on_extern_linked_int() {
std::cout << *int_ptr << std::endl;
}
};
int main() {
temp_on_extern_linked_int<&i>();
}
如程序编译和运行所示。
$ g++-4.8 main.cpp -o main
$ ./main
5
取消注释i
的其他定义会导致编译失败。
$ g++-4.8 main.cpp -o main
main.cpp: In function 'int main()':
main.cpp:17:30: error: '& {anonymous}::i' is not a valid template argument of
type 'int*' because '{anonymous}::i' does not have external linkage
temp_on_extern_linked_int<&i>();
^
该编译器相当有帮助。它明确指出,因为i
没有外部链接,编译失败。
i
的注释定义具有内部链接,因为它是不受外部限制的const。 (§3.4.6)特技的
Variables at namespace scope that are declared const and not extern have internal linkage.
部分未编译为C++ 11。
Why did C++03 require template parameters to have external linkage?
我怀疑脚注可能是C++ 03中的一个剩余部分,其中未命名名称空间中的名称具有外部链接(因为否则它们不能用作模板参数)。作者只是忘记删除它。 – 2014-09-25 01:00:46