如果表达式的类型不依赖,但我们使用它来初始化静态自动变量,会发生什么?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 似乎急切地实例化初始化程序以获取类型。但显然 GCC 没有?我想了解发生了什么。