根据C ++ 1998标准第3.5节第3节,const引用具有内部链接。
具有命名空间作用域(3.3.5)的名称具有内部链接(如果它是
的名称)
明确声明为静态的对象,参考,函数或函数模板,
显式声明为const的对象或引用,既未显式声明为extern,也未声明为具有外部链接;或
- 匿名工会的数据成员。
但是为什么在编译以下代码时会产生多个定义冲突?
// a.cpp
const int& a = 1;
int main()
{
return 0;
}
// b.cpp
const int& a = 1;
然后编译代码。
$ g++ a.cpp b.cpp
/tmp/ccb5Qi0M.o:(.bss+0x0): multiple definition of `a'
/tmp/ccD9vrzP.o:(.bss+0x0): first defined here
collect2: error: ld returned 1 exit status
如果const引用更改为const,如下所示
// a.cpp
const int a = 1;
int main()
{
return 0;
}
// b.cpp
const int a = 1;
可以编译。
答案 0 :(得分:2)
引用本身不是const
,只是它引用的对象;所以(可以说)这个规则并没有给出参考内部联系。
将引用声明为const
是没有意义的。 C ++ 11标准澄清了措辞:
显式声明为
const
或constexpr
且既未明确声明extern
也未声明具有外部链接的变量
没有提到声明const
的引用的荒谬概念。
答案 1 :(得分:0)
我认为@Mike是正确的,这不是新事物,只是一点点提示。
有引用和引用的对象,对象可以是常量然后是内部链接,但引用本身永远不能是常量,因为它没有CV概念(引用在声明期间初始化,然后从不转移到某个对象否则,我记得GCC抱怨如果你提供一个常量引用,意味着int const& r = o;虽然VS没有抱怨,这没有意义),因为引用既不是常量也不是静态,那么声明跨越源文件
答案 2 :(得分:0)
这是一个具有最常量引用的程序。它编译并与C ++ 17(try it)链接:
// a.cpp
extern const int& ir;
int main() { return ir; }
// b.cpp
constexpr const int& ir = 42;
如您所见,ir
可以从另一个翻译单元引用,即它具有外部链接。
结论:全局引用变量具有外部链接,除非声明为static
或在匿名名称空间中。同样,引用上的constexpr
关键字不会使引用成为对引用者(try it)的不变看法。
并且constexpr
引用不是隐式的inline
。这是C ++ 17(try it)中ir
的重新定义:
// a.cpp
constexpr const int& ir = 42;
int main() { return ir; }
// b.cpp
constexpr const int& ir = 42;
如果在两个文件中都将inline
放在ir
的声明之前,则会编译并链接(try it)。