内联静态自动化的初始化程序"sizeof(T)"...是否需要实例化?

Joh*_*itb 5 c++ gcc clang c++17 inline-variable

如果表达式的类型不依赖,但我们用它来初始化静态自动变量会发生什么?GCC和Clang的行为不同

template<typename T>
struct A {
   static inline auto x = sizeof(T{}.f);
};

A<int> a;
Run Code Online (Sandbox Code Playgroud)

GCC不会引发错误.但Clang认为这是无效的,因为它实例化了"sizeof"的操作数.GCC似乎跳过了那一步因为sizeof(T{}.f)总是有类型size_t(不依赖于类型),所以它已经知道x没有实例化的类型.如果我们参考x,例如,两个编译器都会顺从拒绝该程序(void) a.x;.

它甚至必须解决这种类型x吗?使用C++ 14向上语言允许将事物(如函数)保留为"占位符类型"并进行延迟实例化以便稍后查找实际返回类型,如果我没记错的话.它是否也必须应用于此x,所以保持x占位符类型直到我们提到a.x

根据标准,什么编译器是正确的?


编辑

有人问道

嗯,不应该这相当于此吗?

template<typename T>
struct A {
   static const std::size_t x;
};

template<typename T>
inline constexpr std::size_t A<T>::x = sizeof(T{}.f);
Run Code Online (Sandbox Code Playgroud)

在我的问题中,差异以及我关注的是我的问题中的静态数据成员auto.因此,为了知道类型x,您需要知道初始化程序的类型.Clang似乎急切地实例化初始化程序以获得类型.但海湾合作委员会显然没有?我想了解发生了什么.

Bar*_*rry 2

来自[temp.inst]/3

除非类模板或成员模板的成员已显式实例化或显式特化,否则当在需要成员定义存在的上下文中引用特化时,会隐式实例化该成员的特化;特别是,静态数据成员的初始化(以及任何相关的副作用)不会发生,除非静态数据成员本身以需要静态数据成员的定义存在的方式使用。

简单地编写A<int> a;noes 不会A<int>::x以要求其定义存在的方式使用,因此不应发生其初始化。海湾合作委员会是正确的。