可变参数泛型 lambda 和函数重载



我定义了以下可变参数通用 lambda 和重载foo()函数。

template <typename Lambda>
auto bar(Lambda&& lambda) {
return [lambda = std::forward<Lambda>(lambda)](auto&& ...args) {
return lambda(std::forward<decltype(args)>(args)...);
};
}
void foo(std::function<void()>&& cmd, std::function<void()>&& callback) { std::cout << "void" << std::endl; }
void foo(std::function<bool()>&& cmd, std::function<bool()>&& callback) { std::cout << "bool" << std::endl; }

以下 3 个foo()调用打印"void"。

int main()
{
// 1
foo(
bar( []() {} ),
bar( []() {} )
);
// 2
foo(
bar( []() { return true; } ),
bar( []() {} )
);
// 3
foo(
bar( []() {} ),
bar( []() { return true;} )
);
// 4) compiler error: foo is ambiguous
// foo(
//     bar( []() { return false; } ),
//     bar( []() { return true; } )
// );
}

你能帮我理解为什么它成功编译语句 1-3 但无法编译语句 4 吗?

海湾合作委员会 7.5.0

std::function<void()>可以存储任何返回类型(void与否(的函数,其返回值将被丢弃。

因此,在 (4( 中,两个重载都适用,编译器无法决定使用哪一个。

另一方面,在 (1(、(2( 和 (3( 中,两个 lambda 中至少有一个返回void,因此foobool重载不适用。


可能的解决方案是:

  • 当将函子传递到foo时,首先将其转换为std::function的适当专用化。(看起来不太好(

  • std::function编写一个自定义包装器/替换器,构造函数使用不同的 SFINAE。(需要努力(

  • foo作为模板(使用模板参数作为回调的类型(。然后使用decltype确定返回类型,并采取相应的操作。(这是我会做的(

最新更新