6

考虑以下代码:

const int a = 0;
const std::string b = "hi";

inline void f_a1()
{
    std::cout << a;
}

inline void f_b1()
{
    std::cout << b;
}

inline void f_a2()
{
    std::cout << &a;
}

inline void f_b2()
{
    std::cout << &b;
}

假设此代码存在于将包含在多个翻译单元中的头文件中。

我对内联函数的理解是,它们在每个翻译单元中必须完全相同。

我对上面使用的常量的理解是它们是隐式的,static即内部链接。这意味着每个翻译单元都有自己的副本。

由于上面的内联函数依赖于这些常量,这些函数中的哪一个(如果有)是正确的?

4

1 回答 1

6

如果包含在多个翻译单元中,则唯一有效的函数是f_a1.

相关子句是[basic.def.odr] /6,它声明一个inline函数可以出现在多个翻译单元中,但前提是:

[...] const如果对象在 D 的所有定义中具有相同的文字类型,并且该对象使用常量表达式 (5.19) 进行初始化,并且对象不是 odr-used,并且该对象在 D 的所有定义中具有相同的值;

由于对象是const,它们具有每个[basic.link] /3 的内部链接:

具有命名空间范围(3.3.6)的名称如果是 [...] 的名称,则具有内部链接
- 一个非易失性变量,显式声明为 const 或 constexpr 且既未显式声明 extern 也未先前声明具有外部链接 [ ...]

但是,获取变量的地址或形成对变量的引用(例如,用于参数传递)是odr-use,因此f_a2f_b2是无效的。 f_b1也是无效的,因为ostream输出运算符 forstd::string通过引用获取其参数;即使它通过值获取其参数,隐式调用的复制构造函数也会通​​过引用 获取其参数。f_a1可以,因为int流出运算符按值获取其参数,并且复制 an 的值int const不是 odr-use。

于 2015-02-27T13:25:30.767 回答