Наборы, состоящие из комбинации элементов и других наборов, используемых для конструирования наборов в C ++ - PullRequest
1 голос
/ 18 ноября 2010

У меня есть несколько стандартных наборов целых чисел, к которым мне нужно иметь доступ из нескольких единиц перевода. Цель состоит в том, чтобы взять эти стандартные наборы и поместить их в локальные наборы в зависимости от контекста кода.

Например, лучшее решение, которое у меня есть:

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

Они не обязательно должны быть константными глобальными переменными, на самом деле, я бы предпочел функции, но если бы они были функциями, мне пришлось бы добавлять дополнительную строку и дополнительную переменную set каждый раз, когда я хотел бы использовать более одного.

Это будет выглядеть примерно так (с еще одним стандартным набором, чем раньше):

    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 ]

2 голосов
/ 18 ноября 2010

Какие-то конкретные ограничения производительности?Вы можете просто реализовать добавление, которое вы используете в конце:

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 голос
/ 18 ноября 2010

Локальный макрос (как у вас здесь, ключ #undef), вероятно, является самым чистым решением, когда вы представляете проблему. Тем не менее, вы не очень много говорили о , почему вы это делаете, и эта информация может обеспечить лучшее решение.

Я бы использовал макрос в "противоположном" направлении:

#define COMMON (10)(8)

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

#undef COMMON
0 голосов
/ 18 ноября 2010

Чтобы украсть и слегка подправить ответ Стива (так как я не могу его редактировать).Я думаю, что лучшим решением является реализация оператора + для множеств.

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;
}
...