【发布时间】:2017-11-09 08:10:47
【问题描述】:
如果表达式的类型不依赖,但我们使用它来初始化静态自动变量,会发生什么? 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 没有?我想了解发生了什么。
【问题讨论】:
-
不是任何想象的规范性参考。但众所周知,GCC 有时会跳过步骤,所以我不会感到惊讶。
-
呃,这不应该等同于this 吗?这在两个编译器中都可以编译(但请参阅注释) PS:问题标题说“constexpr inline”,但代码示例没有...
-
@MassimilianoJanes 更新
标签: c++ gcc clang c++17 inline-variable