CRTP base private constructor and derived friend class cause compilation error using C++17 和统一初始化
CRTP base private constructor and derived friend class cause compilation error using C++17 and uniform initialization
我有以下代码:
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();
}
出于某种原因,由于 'x' 变量的 'non-compilable' 初始化,使用 C++17 编译失败。编译器说:
Base::Base() [with T = Derived]' is private within this context
但如您所见,下面我正在创建一个相同类型的对象,但这次我没有使用统一初始化。
x1 变量可以使用 C++11 或 C++17 标准编译,但 'x' 变量只能在 C++11 模式下编译。这是为什么?导致此问题的标准发生了什么变化?
显然 Derived
是自 C++17 以来的聚合,因此 Derived{}
是聚合初始化。 (基础 类 weren't allowed in aggregates pre-C++17,现在 public non-virtual 基础是允许的。)
意思是Base::Base()
是由调用者直接调用的(main()
),而不是Derived
.
解决方案是将Derived() {}
添加到Derived
以阻止它成为聚合。
我有以下代码:
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();
}
出于某种原因,由于 'x' 变量的 'non-compilable' 初始化,使用 C++17 编译失败。编译器说:
Base::Base() [with T = Derived]' is private within this context
但如您所见,下面我正在创建一个相同类型的对象,但这次我没有使用统一初始化。 x1 变量可以使用 C++11 或 C++17 标准编译,但 'x' 变量只能在 C++11 模式下编译。这是为什么?导致此问题的标准发生了什么变化?
显然 Derived
是自 C++17 以来的聚合,因此 Derived{}
是聚合初始化。 (基础 类 weren't allowed in aggregates pre-C++17,现在 public non-virtual 基础是允许的。)
意思是Base::Base()
是由调用者直接调用的(main()
),而不是Derived
.
解决方案是将Derived() {}
添加到Derived
以阻止它成为聚合。