簡體   English   中英

我無法從 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)

如果忽略並發問題,只依賴mutable bool m_cache_initialized; 初始化為false ,和一個if (!m_cache_initialized) { m_cache = m_computation(); m_cache_initialized = true; } if (!m_cache_initialized) { m_cache = m_computation(); m_cache_initialized = true; } 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 頁的頂部)。

您必須使用 Linux 和 gcc。 此實現的“未記錄”功能是任何使用任何線程相關內容的 C++ 代碼都必須與-lpthread顯式鏈接。

在編譯(使用-std=c++17 )並在沒有-lpthread情況下進行鏈接后,我在 Linux 上重現了您的確切崩潰。 如果與-lpthread顯式鏈接,則顯示的代碼運行良好。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM