[dcl.constexpr]/9
对象声明中使用的 constexpr 说明符将对象声明为 const。
[basic.link]/3.2
具有命名空间范围的名称如果是
-非 volatile const 限定类型的非内联变量,既没有显式声明 extern,也没有先前声明为具有外部链接
没有inline
说明符,is_integral_v
将有内部链接。如果您比较两个指向不同翻译单元中相同变量名的指针,这可能会出现问题。
注意事项:仅当变量是类静态数据成员时,内联说明符与 constexpr 是多余的。
遵循一个容易违反一个定义规则is_integral_v
的例子,如果不是内联的话,可能会发生这种情况。
bad_type_trait.h
template<class T>
constexpr auto bad_is_integral_v=std::is_integral<T>::value;
my_header.h
#include "bad_type_trait.h"
void f(const bool& x);
inline void g()
{
f(bad_is_integral_v<int>);
//g ODR use the static variable bad_is_integral_v.
//"ODR use" approximate definition is:
// the variable is refered by its memory address.
}
源1.cpp
#include "my_header.h"
void my_func1(){
g(); //the definition of g in this translation unit.
}
源代码2.cpp
#include "my_header.h"
void my_func2(){
g(); //is not the same as the definition of g in this translation unit.
}
在两个翻译单元中,变量bad_is_integral_v
被实例化为单独的静态变量。内联函数g()
在这两个翻译单元中定义。的定义内部g()
,变量bad_is_integral_v
是ODR使用的,所以两个的定义g()
是不同的,这违反了一个定义的规则。