boostorg / unordered

Boost.org unordered module
http://boost.org/libs/unordered
Boost Software License 1.0
62 stars 55 forks source link

Error when emplacing in unordered_flat_map with std::atomic value #255

Closed OHNOalan closed 2 months ago

OHNOalan commented 2 months ago

I encountered an error when trying to emplace an std::atomic value into a boost::unordered::unordered_flat_map. Here is a minimal reproducible example:

#include <boost/unordered/unordered_flat_map.hpp>
#include <atomic>

int main()
{
    boost::unordered::unordered_flat_map<int, std::atomic<int>> m;
    m.try_emplace(1,0); // this is where complier complains

    return 0;
}

The above program throws an error when attempting to emplace an std::atomic value into the map. The compiler error message is as follows:

/libs/core/include/boost/core/allocator_access.hpp:529:5: error: no matching function for call to ‘std::pair<const int, std::atomic<int> >::pair(std::pair<int&&, std::atomic<int>&&>)’
joaquintides commented 2 months ago

The problem you're experiencing is due to the fact that boost::unordered_flat_map requires that both its key and mapped types be move constructible, and std::atomic types are not move (or even copy) constructible.

There's a number of ways you can work around this:

#include <boost/unordered/unordered_flat_map.hpp>
#include <atomic>

struct copyable_atomic_int: std::atomic<int>
{
    using super = std::atomic<int>;
    using super::super;
    copyable_atomic_int(const copyable_atomic_int& x): super{x.load()} {}
};

int main()
{
    boost::unordered::unordered_flat_map<int, copyable_atomic_int> m;
    m.try_emplace(1,0);

    return 0;
}

Good luck with your project,

OHNOalan commented 2 months ago

Thank you~