Объединить две константы `std :: set`s в объявлении (не во время выполнения) - PullRequest
2 голосов
/ 08 июля 2020

Я пытаюсь элегантно объявить объект-константу std::set, который был бы слиянием двух других констант std::set объектов.

#include <set>

const std::set<int> set_one = { 1,2,3 };
const std::set<int> set_two = { 11,15 };
const std::set<int> set_all = { 1,2,3,11,15 }; // this is not very elegant, duplication

Объявление объекта set_all таким образом не слишком элегантно, поскольку он дублирует информацию из двух предыдущих строк. Есть ли способ использовать константы set_one и set_two при объявлении set_all?

Примерно так:

const std::set<int> set_all = set_one + set_two; // this does not compile, of course!
  1. Все объекты являются строго константами.
  2. В обоих исходных наборах нет перекрывающихся значений, поэтому уникальность не будет проблемой.
  3. Я знаю, как объединять наборы во время выполнения, это не то, что я ищу.
  4. Я действительно стараюсь не прибегать к таким макросам:
#include <set>

#define SET_ONE 1, 2, 3
#define SET_TWO 11, 15

const std::set<int> set_one = { SET_ONE };
const std::set<int> set_two = { SET_TWO };
const std::set<int> set_all = { SET_ONE, SET_TWO };

1 Ответ

5 голосов
/ 08 июля 2020

Вы можете упаковать их в лямбду и сразу же вызвать (т.е. IIFE ).

const std::set<int> set_all = [&set_one, &set_two]() {
   std::set<int> set{ set_one.cbegin(),set_one.cend() };
   set.insert(set_two.cbegin(), set_two.cend());
   return set;
}(); // ---> call the lambda!

Однако, если у вас есть наборы в глобальная область видимости (например, @ Kevin упомянуто) , вы должны использовать лямбда, которая принимает два набора в качестве аргументов

#include <set>

using Set = std::set<int>;    // type alias
const Set set_one = { 1,2,3 };
const Set set_two = { 11,15 };

const Set set_all = [](const Set& setOne, const Set& setTwo)
{
   Set set{ setOne.cbegin(), setOne.cend() };
   set.insert(setTwo.cbegin(), setTwo.cend());
   return set;
}(set_one, set_two); // ---> call the lambda with those two sets!

или просто

const std::set<int> set_all = []()
{
   std::set<int> set{ set_one.cbegin(),set_one.cend() };
   set.insert(set_two.cbegin(), set_two.cend());
   return set;
}(); // ---> call the lambda!

Я знаю, как объединять наборы во время выполнения, это не то, что я ищу.

Нет , вы не можете создать std::set во время компиляции, поскольку он использует динамическое c выделение . Следовательно, все происходит во время выполнения. Даже указанная выше лямбда.

...