Why does cppreference define type_traits xxx_v shortcuts as inline constexpr
and not just constexpr
?
For example, see is_integral_v
:
template< class T >
inline constexpr bool is_integral_v = is_integral<T>::value;
Is this just a matter of style or is there some difference in behavior? As far as I know constexpr
variables are implicitly inline
.
Edit: Looking at the draft of the latest standard, it also uses inline constexpr
. The question actually applies to the standard, then.
[dcl.constexpr]/9
[basic.link]/3.2
Without
inline
specifier,is_integral_v
would have internal linkage. This could be problematic if you compared two pointers to this same variable name taken in different translation unit.Nota Bene: the inline specifier is redundant with constexpr only if the variable is a class static data member.
Following an exemple of easy violation of the one definition rule that could happen if
is_integral_v
where not inline.bad_type_trait.h
my_header.h
source1.cpp
source2.cpp
In the two translation units, the variable
bad_is_integral_v
is instantiated as separate static variables. The inline functiong()
is defined in these two translation units. Inside the definition ofg()
, the variablebad_is_integral_v
is ODR used, so the two definitions ofg()
are different, which is a violation of the one definition rule.[basic.link]/3.2 applies to names of "a non-inline variable of non-volatile const-qualified type". A variable template isn't a variable, just like a class template isn't a class, a function template isn't a function, and a cookie cutter isn't a cookie. So that rule doesn't apply to the variable template
is_integral_v
itself.A variable template specialization is a variable, however, so there are some questions about whether that rule gives it internal linkage. This is core issue 1713, the direction of which is that the rule is not applicable.
Core issue 1713, however, wasn't resolved in time for C++17. So LWG decided to simply plaster
inline
all over the variable templates just to be safe, because they don't hurt, either.