c++booststd-bitsetboost-bimap

Struggling to create a Boost-Bimap containing std::bitset


I have a number of strings and their bitset equivalents. I need to be able to look up equivalents in both directions, i.e. "str to bitset" and "bitset to str". I believe boost-bimap would be the right container for this job.

I managed to get this to work with strings and integers but my string / bitset bimap does not compile. I am using VS2019 with the latest boost release.

Integer example works:

#include <boost/bimap.hpp>
#include <string>
#include <iostream>

int main()
{
    typedef boost::bimap<std::string, int> bimap_str_int_t;

    bimap_str_int_t bimap1;
    bimap1.insert(bimap_str_int_t::value_type("A", 1));
    std::cout << bimap1.left.at("A") << '\n';  //prints 1
    std::cout << bimap1.right.at(1) << '\n';   // prints A
}

Bitset example fails to compile:

#include <boost/bimap.hpp>
#include <string>
#include <iostream>
#include <bitset>

int main()
{
    typedef std::bitset<3> bitset_t;
    typedef boost::bimap<std::string, bitset_t> bimap_str_bitset_t;

    bimap_str_bitset_t bimap2;
    bitset_t bits{ "010" };

    bimap2.insert(bimap_str_bitset_t::value_type("A", bits));
    std::cout << bimap2.left.at("A") << '\n';
    std::cout << bimap2.right.at(bits) << '\n';
}

The bitset example creates the following compiler error:

boost_test.cpp(20): message : see reference to class template instantiation 'boost::bimaps::bimap' being compiled

I am not sure how to fix this and would greatly appreciate any hints.


Solution

  • The issue is that std::bitset has no operator< - one of the requirements of any STL-like ordered collection.

    To fix this, you need to supply a comparison function - here's one way you might try:

    #include <boost/bimap.hpp>
    #include <string>
    #include <iostream>
    #include <bitset>
    
    typedef std::bitset<3> bitset_t;
    struct compare_bitset {
        bool operator()(const bitset_t& x, const bitset_t& y) const {
            return x.to_ulong() < y.to_ulong();
        }
    };
    
    int main()
    {
        using bitset_set = boost::bimaps::set_of<bitset_t, compare_bitset>;
        typedef boost::bimap < std::string, bitset_set> bimap_str_bitset_t;
    
        bimap_str_bitset_t bimap2;
        bitset_t bits{ "010" };
    
        bimap2.insert(bimap_str_bitset_t::value_type("A", bits));
        std::cout << bimap2.left.at("A") << '\n';
        std::cout << bimap2.right.at(bits) << '\n';
    }