没有默认构造函数的类适用于gcc,但不适用于msvc



我有下面的程序,可以用gcc和clang编译,但不能用msvc c++20编译。现场演示

struct not_default_constructible { not_default_constructible() = delete; };
template<typename T> struct C
{
static constexpr T t{};
};
template<class T>
struct myClass {
C<T> new_t() { return {}; }
};
int main() {
myClass<not_default_constructible> d;
d.new_t();    
}
正如我们所看到的,上面的程序可以在gcc和clang (c++17和c++20)中工作,但是在msvc (c++20)中被拒绝,并报错:
<source>(6): error C2131: expression did not evaluate to a constant
<source>(6): note: failure was caused by call of undefined function or one not declared 'constexpr'
<source>(6): note: see usage of 'not_default_constructible::not_default_constructible'
<source>(15): note: see reference to class template instantiation 'C<T>' being compiled
with
[
T=not_default_constructible
]

所以我想知道c++ 20中是哪个编译器。我的意思是这个程序在c++20中格式是否良好。

MSVC抱怨是不对的。类模板专门化的静态数据成员的定义只有在成员被odr使用时才应该隐式实例化。但是你不能在任何地方使用C<not_default_constructible>::t

如果您确实使用了odr-useC<not_default_constructible>::t,那么它的定义将被隐式实例化,并且在c++ 20中是错误的,因为它将使用已删除的默认构造函数。

在c++ 17中,它仍然是格式良好的,因为not_default_constructible仍然是c++ 17中的聚合类(删除的构造函数不计入该属性,但自c++ 20以来),因此{}将是聚合初始化,实际上不使用默认构造函数。

最新更新