2010-11-18 121 views
1

我有几个标准的整数集,我需要能够从多个翻译单元访问。目标是取这些标准集并根据代码的上下文将它们放入本地集。包含元素和其他集合用于构造C++的集合的集合

举例来说,最好的解决办法我是:

#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; 

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

回答

1

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

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

#define COMMON (10)(8) 

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

#undef COMMON 
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); 
+0

回答得好,不过是明确的转换必要?我认为b.a.list_of会(隐式地)转换成集合。 – 2010-11-18 03:31:07

+0

@Fred:是的,好点。实际上,它不会为我*编译*,因为'set'有两个2-arg构造函数。此外,我不知道为什么我认为我可以称为功能'联盟';-) – 2010-11-18 03:37:12

+0

哈,即使它在这里突出显示,我甚至没有看到'联盟'的问题。 – 2010-11-18 03:38:04

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; 
} 
+0

我决定不这样做,因为我不喜欢和其他人的班上的操作员混在一起。但是,如果操作符处于合理的范围内(例如包含集合的命名空间),我不认为它会造成任何伤害。另外两个容器的“+”的合理含义是连接,返回一些类型的序列...... – 2010-11-18 04:14:10

相关问题