假设我有这两种方法:
// 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)
{
// ...
}
关于c++ - 使用参数包解决重载问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75511781/