【发布时间】:2021-11-16 14:12:33
【问题描述】:
考虑这段代码:
#include <iostream>
#include <type_traits>
struct A
{
A(int x) {std::cout << "A(" << x << ")\n";}
};
struct B : A
{
using A::A;
B(int x, int y) : A(x) {std::cout << "B(" << x << "," << y << ")\n";}
};
struct C : B
{
using B::A; // <--
// C() : B(0,0) {}
};
int main()
{
C c(1);
}
它在 GCC 上编译并打印 A(1),这意味着 B 的实例是在没有调用构造函数的情况下“构造”的。如果取消注释C(),则C c(1); 不再编译(GCC 找不到合适的构造函数)
Clang 没有说using B::A;,但是拒绝编译C c(1);(也找不到合适的构造函数)。
MSVC 停在using B::A;,基本上是说你只能从直接基类继承构造函数。
Cppreference 没有提到从间接基类继承构造函数,所以它似乎是不允许的。
这是 GCC 和 Clang 的错误,还是这里发生了什么?
【问题讨论】:
-
根据 C++ 标准,您只能将 using 声明用于直接基类的构造函数。
-
我认为值得在这里添加
c++20标签,因为在这个例子中,GCC 的行为在 C++17 和 C++20 模式下明显改变。