class 层次结构中的 C++ 'using' 关键字,具有函数调用运算符和私有继承

C++ 'using' keyword in class hierarchy with function call operator and private inheritance

我偶然发现了一些我不太明白的东西。我有一个使用私有继承的 class 层次结构,其中每个 struct 都定义了不同的函数调用运算符。奇怪的是,来自最顶层 struct 的函数调用运算符在最派生的 struct 中可用,尽管 using 指令仅在第一个派生的 struct 中使用.但是,正如预期的那样,在那里无法访问常规函数 foo。示例:

#include <string>
#include <vector>
#include <iostream>

struct A {
    void foo() {}
    void operator()(bool) {
        std::cout << "bool\n";
    }
};

struct B : private A {
    using A::foo;
    using A::operator();
    
    void operator()(std::string) {}
};

struct C : private B {
    using B::operator();
    
    void operator()(std::vector<int>) {}
};

struct D : private C {
    using C::operator();
    
    void operator()(std::vector<double>) {}
};

int main() {

    D d{};

    d(false);  // <-- works!
    //d.foo(); // <-- error: ‘void A::foo()’ is private within this context

    return 0;
}

我在尝试使用 C++17 之前的代码实现与 boost::apply_visitor 一起使用的 C++17 overload 对象时偶然发现了这一点。我使用递归继承解决了它,其中每个对象都引入其直接基 class 的函数调用运算符,如下所示:

    template<typename T, typename... Ts>
    struct visitor : private T, private visitor<Ts...> {
        using T::operator();
        using visitor<Ts...>::operator();

        visitor(T func, Ts... tail) : T{ std::move(func) }, visitor<Ts...>{ std::move(tail)... } {}
    };

    template<typename T>
    struct visitor<T> : private T {
        using T::operator();

        visitor(T func) : T{ std::move(func) } {}
    };

    template<typename... Ts>
    visitor<Ts...> make_visitor(Ts&&... funcs) {
        return visitor<Ts...>{ std::forward<Ts>(funcs)... };
    }

我想了解为什么所有运算符在最派生的对象中都可用。这就是我想出上面例子的方式。编译器是 g++ 11.1.0.

谁能告诉我这是怎么回事?

正如其他人在评论中指出的那样,原来我的想法有误。 using 引入了 all 相应基础 class 中可用的运算符,包括由基础 class 本身导入的运算符,因此所有运算符都将在最底部的对象中可用。另一方面,foo只是传给了B