c++ - 我无法从 C++ 中的函数式编程中重现函数记忆
问题描述
以下代码应该几乎是第 6 章第 1 节末尾的《C++ 函数式编程》一书的副本:
#include <iostream>
#include <utility>
#include <mutex>
template<typename F>
class lazy_val {
private:
F m_computation;
mutable decltype(m_computation()) m_cache;
mutable std::once_flag m_value_flag;
public:
lazy_val(F f)
: m_computation(f)
{}
operator const decltype(m_computation())& () const {
std::call_once(m_value_flag, [this](){
m_cache = m_computation();
});
return m_cache; // the execution never gets to this line
}
};
int expensive() {
std::cout << "expensive call...\n";
return 7;
}
int main() {
std::cout << "non memoized" << '\n';
std::cout << expensive() << '\n';
std::cout << expensive() << '\n';
std::cout << expensive() << '\n';
const auto expensive_memo = lazy_val(expensive);
std::cout << "memoized" << '\n';
std::cout << expensive_memo << '\n'; // crash happens here
std::cout << expensive_memo << '\n';
std::cout << expensive_memo << '\n';
}
但是,当我执行它时(编译正常),我收到此错误:
non memoized
expensive call...
7
expensive call...
7
expensive call...
7
memoized
terminate called after throwing an instance of 'std::system_error'
what(): Unknown error -1
Aborted (core dumped)
如果忽略并发问题并且仅依赖于mutable bool m_cache_initialized;
初始化为false
和 a if (!m_cache_initialized) { m_cache = m_computation(); m_cache_initialized = true; }
,那么一切正常。
这让我认为问题在于我如何在代码中使用std::call_once
/ 。std::once_flag
但是我看不出它与书中显示的有什么不同(清单 6.2 中的构造函数,但没有初始化m_cache_initialized
to的行false
,类的其余部分位于第 125 页的底部和第 126 页的顶部)。
解决方案
您必须使用 Linux 和 gcc。此实现的“未记录”功能是任何使用任何线程相关内容的 C++ 代码都必须显式链接到-lpthread
.
在编译(使用-std=c++17
)并链接不使用-lpthread
. 显示的代码运行良好,如果与-lpthread
.
推荐阅读
- vhdl - VHDL:端口什么时候可以用作信号?
- python - 重用中间层作为 Keras 中另一个模型的输入
- javascript - 如何在画布中绘制两个具有样式的图像?
- xtext - 在 IBM RSA 9.6.1 上安装 Xtext
- google-apps-script - 表单提交触发器已过期?
- phpstorm - 默认情况下 PhpStorm 流利的设置器
- spinnaker - 大三角帆部署失败:安装问题本地 Debian 部署
- android - 获取 Google API 访问权限并避免 UserRecoverableAuthIOException
- mysql - 结合从 information_schema 中选择和从另一个数据库中更改表
- hibernate - 如何在内存数据库中使用 H2 调试 Spring Boot 存储库?