在我的另一个问题中,我了解到
std::function<asio::awaitable<void>()>
可以自动转换为std::function< void()>
。这会导致如下问题:
我需要编写一个具有两个重载的函数,它们接受两个回调:
std::function<asio::awaitable<void>()>
或std::function<void()>
。根据上一个问题,很明显这是行不通的。
但是如果你将其更改为仅接受
std::function<void()>
类型的回调。虽然传入 std::function<asio::awaitable<void>()>
类型回调同样合法,但回调的真实返回值在函数内部不可用。
当然可以写成两个不同名称的函数。但问题依然存在,
std::function<void()>
的版本会导致非常容易误操作。因为即使你不小心通过了std::function<asio::awaitable<void>
,编译器也不会报错。
对于如何解决上述问题有什么想法吗?
在 C++20 中,您可以使用概念(或在 C++17 SFINEA 中)来“禁用”隐式类型转换,如下所示:
#include <functional>
namespace asio
{
template<typename type_t>
struct awaitable
{
};
}
template<typename signature_t>
concept VoidFunction = std::is_same_v<std::function<void()>,std::function<signature_t>>;
// use a concept or in C++ SFINEA to disable "implicit" type conversion
// now this function will only accept an explicit match
void func(auto VoidFunction /*cb*/)
{
}
void func(std::function<asio::awaitable<void>()> /*cb*/)
{
}
int main()
{
func([]() -> asio::awaitable<void> {
// co_return;
});
}