内联静态自动的初始值设定项"sizeof(T)"...它需要实例化吗?
Initializer "sizeof(T)" of inline static auto... Does it need instantiation?
如果表达式的类型不是依赖的,但我们使用它来初始化静态自动变量,会发生什么?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
,所以在我们引用a.x
之前,保持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似乎急切地实例化初始化器,以便获得类型。但海湾合作委员会显然没有?我想了解发生了什么。
来自[temp.inst]/3:
除非类模板或成员模板的成员已显式实例化或显式专门化,否则当在需要成员定义存在的上下文中引用专门化时,该成员的专门化将隐式实例化;特别是,静态数据成员的初始化(以及任何相关的副作用)不会发生,除非静态数据成员本身的使用方式需要静态数据成员定义的存在
简单地编写A<int> a;
并不意味着不以需要其定义存在的方式使用A<int>::x
,因此不应进行其初始化。gcc是正确的。
相关文章:
- 从C++实例化QML
- 设计一个只能由特定类实例化的类(如果可能的话,通过make_unique)
- 如何创建一个空的全局类并在启动时实例化它
- 在两个类中共享相同的函数调用,并在不需要时避免空实例化
- 约束和显式模板实例化
- 为什么包含windows.h会产生语法错误,从而阻止类的实例化?(C2146,C2065)
- 对象实例化调用构造函数的次数太多
- 如何使用非默认构造函数实例化模板化类
- 静态数据成员模板专用化的实例化点在哪里
- 错误的cv::face FacemarkLBF实例化
- C++的解析器在可以区分比较和模板实例化之前会做什么?
- 为什么 gcc 和 clang 为函数模板的实例化生成不同的符号名称?
- 检查某些类型是否是模板类 std::optional 的实例化
- 我有一个对象,它将在整个程序的持续时间内实例化,但一个类成员不会,我应该动态分配它吗?
- 无法使用 SWIG 在 Python 中实例化C++类(获取属性错误)
- 模板化类构造函数的模板实例化
- 在 c++ 中的模板实例化中使用带有构造函数的类作为类型参数
- 受约束的成员函数和显式模板实例化
- 内联静态自动的初始值设定项"sizeof(T)"...它需要实例化吗?
- 使用 Sizeof、malloc 和 cast 的 C++ 对象实例化