【发布时间】:2020-09-12 17:50:46
【问题描述】:
以下代码应该几乎是C++中的函数式编程一书在第 6 章第 1 节末尾介绍的内容的副本:
#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)
如果忽略并发问题,只依赖初始化为false 的mutable bool m_cache_initialized; 和if (!m_cache_initialized) { m_cache = m_computation(); m_cache_initialized = true; },那么一切正常。
这让我觉得问题在于我如何在代码中使用std::call_once/std::once_flag。但是我看不出它与书中显示的有什么不同(清单 6.2 中的构造函数,但没有将 m_cache_initialized 初始化为 false 的行,并且该类的其余部分位于第 125 页的底部和 126 的顶部)。
【问题讨论】:
标签: c++ multithreading gcc runtime-error std-call-once