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

时间:2017-11-09 08:10:47

标签: c++ gcc clang c++17 inline-variable

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

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

A<int> a;

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);

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

1 个答案:

答案 0 :(得分:2)

来自[temp.inst]/3

  

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

简单地编写A<int> a;不会以要求其定义存在的方式使用A<int>::x,因此不应该进行初始化。 gcc是对的。