如何从静态列表构建Boost bimap?

27

我有这样一个二进制图像:

using MyBimap = boost::bimaps::bimap<
    boost::bimaps::unordered_set_of<A>,
    boost::bimaps::unordered_set_of<B>>;

我希望能够从静态初始化列表构建它,就像对于std::map一样:

MyBimap map{{a1, b1}, {a2, b2}, {a3, b3}};

很不幸,它不起作用,因为bimap不支持初始化列表,所以我尝试了一个解决方法。 Boost 的文档列出了以下构造函数:

 bimap();

 template< class InputIterator >
 bimap(InputIterator first,InputIterator last);

 bimap(const bimap &);

于是我尝试了第二个,就像这样:

std::vector<std::pair<A,B>> v{{a1, b1}, {a2, b2}, {a3, b3}};
MyBimap map(v.begin(), v.end());

这也没有起作用。文档并没有明确说明这个构造函数需要什么类型的迭代器,但显然它不仅仅是一组 std::pair<A, B> 对象的迭代器。那么这个 bimap 的构造函数需要什么样的迭代器呢?

4个回答

31

我使用以下“工厂函数”,它接受一个花括号初始化列表,并返回一个boost::bimap

template <typename L, typename R>
boost::bimap<L, R>
make_bimap(std::initializer_list<typename boost::bimap<L, R>::value_type> list)
{
    return boost::bimap<L, R>(list.begin(), list.end());
}

使用方法:

auto my_bimap = make_bimap<int, int>({{1, 2}, {3, 4}, {5, 6}});

19

C++ 初学者:你可以使用 boost::assign 来生成初始化。我在这里找到了这个解决方案

例子:

#include <boost/bimap.hpp>
#include <boost/assign.hpp>

//declare the type of bimap we want
typedef boost::bimap<int, std::string> bimapType;
//init our bimap
bimapType bimap = boost::assign::list_of< bimapType::relation >
( 1, "one"   )
( 2, "two"   )
( 3, "three" );

//test if everything works
int main(int argc, char **argv)
{
    std::cout << bimap.left.find(1)->second << std::endl;
    std::cout << bimap.left.find(2)->second << std::endl;
    std::cout << bimap.left.find(3)->second << std::endl;
    std::cout << bimap.right.find("one")->second << std::endl;
    std::cout << bimap.right.find("two")->second << std::endl;
    std::cout << bimap.right.find("three")->second << std::endl;

    /* Output:
     * one
     * two
     * three
     * 1
     * 2
     * 3
     */
}

不是使用常规的初始化列表语法,虽然这更可取,但它仍然能够正常工作 :-) - Murphy

10

迭代器begin/end应该用于bimap值序列。

boost::bimap< A, B>::value_type

bimap值很像std::pair,可以使用{a1, b1}语法进行初始化。它们的向量似乎也可以工作,并为构造函数提供可用的迭代器。

好的,这是一个对我而言可以编译和运行的示例(gcc 4.8.2 --std=c++11)。

#include <vector>
#include <boost/bimap.hpp>

using namespace std;
int main() {
    typedef boost::bimap< int, int > MyBimap;

    std::vector<MyBimap::value_type > v{{1, 2}, {3, 4}, {5, 6}};

    MyBimap M(v.begin(),v.end());

    std::cout << "The size is " << M.size()
              << std::endl;

    std::cout << "An entry is 1:" << M.left.at(1)
              << std::endl;
}

2

这会留下一个需要清理的向量,这在某些情况下可能是一个问题。这里有一个短小的辅助类,可以解决您的问题。由于类实例是临时的,因此无论在何处使用它,都会立即进行清理。这是基于https://dev59.com/8nVC5IYBdhLWcg3w9F89#1730798

// helper for bimap init (simple, lightweight version of boost::assign)
template <typename T, typename U>
class create_bimap
{
    typedef boost::bimap< T, U > bimap_type;
    typedef typename bimap_type::value_type value_type;
private:
    boost::bimap<T, U> m_map;
public:
    create_bimap(const T& left, const U& right)
    {
        m_map.insert( value_type(left, right) );
    }

    create_bimap<T, U>& operator()(const T& left, const U& right)
    {
        m_map.insert( value_type(left, right) );
        return *this;
    }

    operator boost::bimap<T, U>()
    {
        return m_map;
    }
};

使用方法如下:

boost::bimap<string,int> myMap = create_bimap<string,int>
    ("c",1)
    ("b",2)
    ("a",3);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接