If it is included in several translation units, the only valid function is f_a1 .
The corresponding sentence [basic.def.odr] / 6, which states that the inline function can be displayed in several translation units, but only on condition that:
[...] the name can refer to a non-volatile const object with internal or no binding if the object has the same literal type in all definitions of D and the object is initialized with the constant expression (5.19) and the object is not used as odr, but an object has the same meaning in all definitions of D;
Since the objects are const , they have an internal connection at [basic.link] / 3:
A name that has a namespace scope (3.3.6) has an internal relationship if that name [...]
- an immutable variable that is explicitly declared as const or constexpr and is not explicitly declared extern or previously declared to have an external connection [...]
However, using an address or linking to a variable (for example, to pass an argument) is odr-use, so f_a2 and f_b2 are not valid. f_b1 also invalid because the ostream output ostream for std::string takes its argument by reference; and even if he accepted his argument by value, the implicitly called copy constructor would accept its argument by reference. f_a1 OK, because the stream operator int takes its argument by value, and copying the value of int const is not acceptable.
source share