c++ - 使用参数包解决重载问题

标签 c++ variadic-functions overload-resolution

假设我有这两种方法:

// Overload 1
template <typename T, typename... Args>
void Foo(Args&&... args)
{
    // do things with T, args...
}

// Overload 2
template <typename T, typename... Args>
void Foo(std::function<void(T&)> && func, Args&&... args)
{
    // do things with func, T, args...
}

我试图这样调用它:

Foo<MyClass>([](auto& my_class){
    // do things with my_class
});

我打算调用 Overload 2。问题是它实际上解析为 Overload 1。我可以通过显式设置 std::function<void(MyClass&)> func 来使其工作。变量并在删除 std::function 上的右值后传递该变量,但我想尝试让它与 lambda 一起工作。如果我提供另一个参数,它也可以与 lambda 一起使用,但我不会再提供另一个参数。

不应该使用 std::function 的方法吗?论证要更专业一些?为什么它选择了错误的过载?我读过overload resolution规则,但我没有看到/理解该行为的原因。

鉴于它适用于显式参数,我假设它与从 lambda 到 std::function 的隐式转换有关。 ,该转化的排名低于仅使用 Args ,即使它更专业。我能做些什么来保留 lambda 吗?

最佳答案

Shouldn't the method with the std::function argument be more specialized?

是的,过载 2 比过载 1 更专业

Why is it choosing the wrong overload?

Lambda 不是 std::function,因此第一次重载是更好的匹配(完全匹配)。

Is there anything I can do to keep the lambda?

使用常规模板参数而不是std::function:

template <typename T, typename F, typename... Args>
requires (std::invocable<F, T&>)
void Foo(F&& func, Args&&... args)
{
    // ...
}

Demo

关于c++ - 使用参数包解决重载问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75511781/

相关文章:

c++ - 重载解析和用户定义转换

c++ - 这个例子可以用指针而不是全局变量来完成吗?

c++ - 如何以编程方式从 IHTMLDocument 获取 documentMode?

c - 将类型作为参数,如 C 中的 va_arg

c++ - 可变参数模板函数是否以相反的顺序调用 lambda 参数?

c - 如何将结构传递和访问 C 中的可变参数函数

c++ - "std::cout << std::endl;"如何编译?

c++ - 如何通过按 Esc 键使非模态 QDialog 不可取消?

c++ - 通过存储指向成员函数的指针的虚拟行为

c++ - 编译器选择错误的重载而不是有效的重载