Why does cppreference define type_traits xxx_v shortcuts as inline constexpr and not just constexpr?

前端 未结 2 724
眼角桃花
眼角桃花 2020-12-16 12:58

Why does cppreference define type_traits xxx_v shortcuts as inline constexpr and not just constexpr?

For example, see is_integral_v:

2条回答
  •  时光说笑
    2020-12-16 13:19

    [dcl.constexpr]/9

    A constexpr specifier used in an object declaration declares the object as const.

    [basic.link]/3.2

    A name having namespace scope has internal linkage if it is the name of

    -a non-inline variable of non-volatile const-qualified type that is neither explicitly declared extern nor previously declared to have external linkage

    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

    template
    constexpr auto bad_is_integral_v=std::is_integral::value;
    

    my_header.h

    #include "bad_type_trait.h"
    void f(const bool& x);
    
    inline void g()
      {
      f(bad_is_integral_v);
      //g ODR use the static variable bad_is_integral_v.
      //"ODR use" approximate definition is: 
      //     the variable is refered by its memory address.
      }
    

    source1.cpp

    #include "my_header.h"
    void my_func1(){
       g(); //the definition of g in this translation unit.
       }
    

    source2.cpp

    #include "my_header.h"
    void my_func2(){
       g(); //is not the same as the definition of g in this translation unit.
       }
    

    In the two translation units, the variable bad_is_integral_v is instantiated as separate static variables. The inline function g() is defined in these two translation units. Inside the definition of g(), the variable bad_is_integral_v is ODR used, so the two definitions of g() are different, which is a violation of the one definition rule.

提交回复
热议问题