在未使用的默认成员初始值设定项中使用仍然是 odr 使用吗?

use*_*522 12 c++ one-definition-rule template-instantiation implicit-instantiation

即使任何构造函数都没有使用默认成员初始值设定项,在默认成员初始值设定项中使用仍然是 odr 使用吗?

例如,该程序是否格式错误,因为g<A>使用了 odr,因此其定义被隐式实例化?

template<typename T>
void g() { sizeof(T); }

struct A;

struct B {
    B() : i{} {};

    int i = (&g<A>, 0);
};

int main() { }
Run Code Online (Sandbox Code Playgroud)

MSVC 认为不会。Clang、GCC 和 ICC 认为是的。https://godbolt.org/z/zrr9oEdfe

Dav*_*ing 8

正如评论中所述g<A>,是 odr 使用的。然而,它一个可用的定义,所以这里不存在不可诊断的违规;MSVC接受它是错误的。(即使没有构造函数声明也是如此;隐式声明的B::B()从未定义,但默认成员初始值设定项仍然是一个 odr-use,就像这里一样。)