c++ - 使用 Y 组合器的空参数包的模板替换失败
问题描述
我正在尝试制作一个函数,该函数将使用boost::asio::posix::stream_descriptor
. 我使用async_read_some
而不是boost::asio::async_read
因为一旦读取大量数据就立即通知我很重要。从管道读取数据后我想做的是
- 移动缓冲区的写入器指针
- 用新得到的数据做点什么
- 安排读取更多数据
我想复制尽可能少的代码,所以我最终得到了一个函数式编程混乱,我很想知道它为什么不起作用。
asio::posix::stream_descriptor inputPipe{context, input.fd};
char buffer[2048]; // simple buffer for demonstration purposes
char* end = buffer + 2048;
char* writer = buffer;
// the interesting part
yCombinator([&](auto&& self_) {
inputPipe.async_read_some(asio::buffer(writer, end - writer), [&](boost::system::error_code errorCode_, size_t transferedCount_) -> void {
writer += transferedCount_;
// ... be something, go somewhere, do something, make things change ...
self_(self_); // self_ contains the async_read_some, so it schedules the next read
});
})();
我自豪地展示yCombinator
为:
template<typename Fn>
constexpr auto yCombinator(Fn&& fn_) noexcept {
return [capture = std::tuple{std::forward<Fn>(fn_)}](auto&&... args_) constexpr noexcept(std::is_nothrow_invocable_v<Fn, decltype(args_)...>)->std::invoke_result_t<Fn, decltype(args_)...> {
return std::invoke(std::get<0>(capture), std::get<0>(capture), std::forward<decltype(args_)>(args_)...);
};
}
目前上述代码无法编译。G++ 抱怨说candidate template ignored: substitution failure [with args_:auto = <>]: no type named 'type' in 'std::invoke_result<(lambda at redacted.cpp:80:21)>'
. 我知道这与从yCombinator
. 我想问题可能args_
是一个空的参数包,但我不确定如何处理它。但同时,如果这是问题所在,那为什么这个std::is_nothrow_invocable_v
特征看起来一切都好呢?
解决方案
你有几个问题:
首先,返回类型/noexcept 和函数体不匹配:前者Fn
中的miss
template<typename Fn>
constexpr auto yCombinator(Fn&& fn_) noexcept {
return [capture = std::tuple{std::forward<Fn>(fn_)}](auto&&... args_) constexpr
noexcept(std::is_nothrow_invocable_v<Fn, Fn, decltype(args_)...>)
// ^^
-> std::invoke_result_t<Fn, Fn, decltype(args_)...>
// ^^
{
return std::invoke(std::get<0>(capture),
std::get<0>(capture),
std::forward<decltype(args_)>(args_)...);
};
}
然后,要推断未提供的返回类型,我们必须“查看”主体,因此self_
在推断之前使用返回类型。
解决方案是明确提供类型:
yCombinator([&](auto&& self_) -> void
// ^^^^^^^
{
// ...
self_(self_);
})();
推荐阅读
- sql - 在 PostgreSQL 中为给定行选择所有具有 NOT NULL 值的列
- python - 错误:无法识别的指令格式:
- winapi - 如何使用自定义数据在外螺纹上安装挂钩程序?
- node.js - 在nodejs中只接收带有对象标签的空数组
- python - 用于翻译的 TensorFlow 数据集 - 如何使用 WMT14 手动下载?
- javascript - 使用 Javascript 将标签 [start] [end] 包裹在 textarea 中的选定文本周围
- prometheus - Unavailable Prometheus service with WAL segment loaded entries in log file
- ipv6 - Formula for Supernetting the multiple blocks of IPv6 pools
- javascript - Image Crop And Compression before upload
- c++ - Initialise char array with string variable in C++?