我无法通过 C++ 中的函数式编程重现函数记忆

I can't reproduce the function memoization from Functional Programming in C++

下面的代码应该几乎是 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)

如果忽略并发问题,只依赖初始化为 falsemutable 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 的行,其余的 class 位于第 125 页底部和第 126 页顶部)。

您必须使用 Linux 和 gcc。此实现的一个“未记录”功能是任何使用任何 thread-related 内容的 C++ 代码都必须与 -lpthread.

显式链接

我在编译(使用 -std=c++17)和不使用 -lpthread 的情况下链接后,在 Linux 上重现了您的确切崩溃。如果与 -lpthread.

显式链接,则显示的代码运行良好