CRTP基私有构造函数和派生的友元类使用C++17和统一初始化导致编译错误



我得到了以下代码:

struct B
{
B(int) {}
};
template <typename T>
class Base : public B
{
friend T;
Base() : B(1) {}
};
class Derived : public Base<Derived>
{
public:
void do_sth() const {}
};
int main()
{
auto x = Derived{}; //Compiles only when using C++11
auto x1 = Derived(); //Compiles using C++17/20 flag
x.do_sth();
x1.do_sth();
} 

由于某些原因,当使用C++17时,由于"x"变量的"不可编译"初始化而导致编译失败。Complator说:

Base::Base(([withT=Derived]'在此上下文中是私有的

但正如您所看到的,下面我正在创建一个相同类型的对象,但这次我没有使用统一初始化。x1变量可以使用C++11或C++17标准编译,但"x"变量只能在C++11模式下编译。为什么?导致此问题的标准发生了什么变化?

编译器资源管理器

显然Derived是C++17以来的一个聚合,因此Derived{}是一个聚合初始化。(在C++17之前的聚合中不允许基类,现在允许公共非虚拟基类。(

这意味着Base::Base()是由调用者直接调用的(main()(,而不是Derived

解决方案是将Derived() {}添加到Derived以阻止其成为聚合。

最新更新