C++:使用声明和重载范例

MaP*_*aPo 3 c++ overloading c++17

我正在查看此页面有关 C++17 的“新”功能。特别是我理解几乎所有以下代码:

#include <iostream>
#include <variant>

struct Fluid { };
struct LightItem { };
struct HeavyItem { };
struct FragileItem { };

template<class... Ts> struct overload : Ts... { using Ts::operator()...; };
template<class... Ts> overload(Ts...) -> overload<Ts...>;

int main() {
    std::variant<Fluid, LightItem, HeavyItem, FragileItem> package;

    std::visit(overload{
        [](Fluid& )       { std::cout << "fluid\n"; },
        [](LightItem& )   { std::cout << "light item\n"; },
        [](HeavyItem& )   { std::cout << "heavy item\n"; },
        [](FragileItem& ) { std::cout << "fragile\n"; }
    }, package);
}
Run Code Online (Sandbox Code Playgroud)

我不明白的是

using Ts::operator()...;
Run Code Online (Sandbox Code Playgroud)

在 struct 的定义内overload。据我所知,这样使用using关键字是为了确保operator()public。但在我看来,就 lambda 而言,它已经公开了。所以我想说这是多余的。我尝试编译并执行

template<class... Ts> struct overload : Ts... { };
Run Code Online (Sandbox Code Playgroud)

一切正常。我错了吗?我错过了什么吗?

Jar*_*d42 5

using目的不仅是为了改变可访问性,而且是为了“解决”歧义和/或取消隐藏基本方法。

请参阅 https://en.cppreference.com/w/cpp/language/unqualified_lookup#Member_function_definition

否则,如果 Bi 和 C 中的声明集不同,则结果是不明确的合并:C 的新查找集具有无效声明以及先前合并到 C 中并从 Bi 引入的子对象的并集。如果稍后将其丢弃,则此无效查找集可能不会成为错误。

struct Base1
{
    void foo() {}
};

struct Base2
{
    void foo(int) {}
};

struct D : Base1, Base2
{
    // using Base1::foo; // Those would solve the ambiguity
    // using Base2::foo;

    void bar()
    {
        foo(); // ambiguous
    }
}

struct D2 : Base1
{
    // using Base1::foo; // This would unhide Base1::foo

    void foo(char) {} // hides Base1::foo

    void bar()
    {
        foo(); // wrong, find D2::foo(char)
    }
}
Run Code Online (Sandbox Code Playgroud)

using Ts::operator()...;那么只是可变参数语法。