由元素和其他集合组成的集合,用于在C ++中构造集合

时间:2010-11-18 02:23:34

标签: c++ boost set std

我有几个标准的整数集,我需要能够从多个翻译单元访问。目标是采用这些标准集并根据代码的上下文将它们放入本地集中。

例如,我的最佳解决方案是:

#include <boost/assign/list_of.hpp>
#include <set>

const std::set<int> set9 =
    boost::assign::list_of(4)(10)(108);

const std::set<int> set10 =
    boost::assign::list_of(3)(5)(10)(108);

const std::set<int> set11 =
    boost::assign::list_of(2)(3)(5)(101);

int main(void)
{
    std::set<int> my_set(set9);
    my_set.insert(set11.begin(), set11.end());

    return 0;
}

它们不需要是常量全局变量,事实上,我可能更喜欢函数,但如果它们是函数,那么每次我想使用多个函数时,我都必须添加额外的行和额外的变量。

它看起来像这样(比以前多一个标准集):

    std::set<int> my_set(get_set9());
    std::set<int> extra_line(get_set11());
    my_set.insert(extra_line.begin(), extra_line.end());
    std::set<int> another_extra_line(get_set12());
    my_set.insert(another_extra_line.begin(), another_extra_line.end());

除非我遗漏了什么?

我更喜欢功能的原因是存在额外的复杂性。在常量集中,存在具有连接含义的重复值,因此我不希望每次重复它们以防有变化(并防止代码重复)。

在我之前的例子中,说10和108是连接的,应该总是一起出现。如果这些是函数我可以让get_set11()和get_set12()调用一个公共函数(比如get_set2()只有10和108)。但是,使用常量集方法,我不确定如何构建包含其他集的这些常量集。我提出的最好的是:

#include <boost/assign/list_of.hpp>
#include <set>

#define APPLY_COMMON_SET(prev) \
    prev(10)(8)

const std::set<int> set2 =
     APPLY_COMMON_SET(boost::assign::list_of);

const std::set<int> set9 =
     APPLY_COMMON_SET(boost::assign::list_of(4));

const std::set<int> set10 =
     APPLY_COMMON_SET(boost::assign::list_of(3)(5));

const std::set<int> set11 =
    boost::assign::list_of(2)(3)(5)(101);

#undef APPLY_COMMON_SET

int main(void)
{
    std::set<int> my_set(set9);
    my_set.insert(set11.begin(), set11.end());

    return 0;
}

哪个有效,但我更愿意避免使用预处理器宏。

这不能编译,但我希望能够做到这样的事情:

const std::set<int> set2 =
    boost::assign::list_of(10)(108)

const std::set<int> set9 =
    boost::assign::list_of(4) + set2;

const std::set<int> set10 =
    boost::assign::list_of(3)(5) + set2;

有没有办法在没有宏的情况下做到这一点,或者这是我唯一的选择?

3 个答案:

答案 0 :(得分:2)

任何特定的性能限制?您可以实现最后使用的添加:

typedef std::set<int> intset;

intset onion(intset lhscp, const intset &rhs) {
    lhscp.insert(rhs.begin(), rhs.end());
    return lhscp;
}

const intset set10 = onion(boost::assign::list_of(2)(5), set2);

答案 1 :(得分:1)

当你提出问题时,本地宏(就像你在这里,关键是#undef)可能是最干净的解决方案。但是,你没有多说为什么你这样做,而且这些信息可能提供更好的解决方案。

我会在“相反”方向使用宏:

#define COMMON (10)(8)

const std::set<int> set10 =
    boost::assign::list_of(3)(5) COMMON;

#undef COMMON

答案 2 :(得分:0)

窃取并稍微调整史蒂夫的答案(因为我无法编辑)。我认为最好的解决方案是为集合实现operator +。

std::set<int> operator+(std::set<int> lhs, const std::set<int> &rhs)
{
    lhs.insert(rhs.begin(), rhs.end());
    return lhs;
}

完成此操作后,集合是否来自全局常量或函数并不重要,它们都可以作为构造函数的参数:

#include <boost/assign/list_of.hpp>
#include <stdio.h>
#include <set>

typedef std::set<int> intset;
intset operator+(intset lhs, const intset &rhs)
{
    lhs.insert(rhs.begin(), rhs.end());
    return lhs;
}

const intset set2 =
    boost::assign::list_of(10)(108);

const intset set9 =
    boost::assign::list_of(4) + set2;

intset get_set11(bool flag)
{
    if(flag)
    return set2 + boost::assign::list_of(6);
    else
    return set9;
}


int main(void)
{
    intset my_set(set9 + get_set11(true));
    return 0;
}