未使用的static const/constexpr成员变量实例化:哪个编译器合规?
问题:类模板未使用的static成员变量错误诊断,哪个编译器符合C++标准?
以下是包含static const和static constexpr成员变量的类模板代码:
template <class T> struct S { // MSVC: clang: static const bool value1 = T::value1; // error error static constexpr bool value2 = T::value2; // error OK }; S<void> s;
实例化S<void>时,这些成员变量存在语法错误(void没有value1/value2成员),但它们并未被使用。MSVC对两个成员都报错,而Clang仅对static const的value1报错,对static constexpr的value2不报错。请问哪个编译器的处理符合C++标准?
回答
Clang的处理符合C++标准。
核心依据是C++标准的模板延迟实例化规则:类模板的成员并非在类实例化时全部处理,只有当成员被实际使用时才会触发实例化和错误检查,但存在细节差异:
static const成员的类内初始化属于模板的“声明性”内容,会在类模板实例化阶段被检查,因此value1的错误必须被诊断;static constexpr成员的类内初始化属于“定义性”内容,只有当该成员被ODR使用(比如取地址、绑定到引用等)时才会触发实例化和错误检查。
在这个例子中,S<void>的两个成员都没有被ODR使用,因此编译器不需要诊断value2的错误,但必须诊断value1的错误——这正是Clang的行为。MSVC错误地对未被使用的static constexpr成员也进行了错误诊断,不符合标准规则。
内容的提问来源于stack exchange,提问作者Dr. Gut
相关产品推荐
相关产品推荐

