简体   繁体   中英

Merge two constant `std::set`s in declaration (not in run-time)

I am trying to elegantly declare a constant std::set object that would be a merger of two other constant std::set objects.

#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

Declaring set_all object this way is not too elegant, as it duplicates information from the previous two lines. Is there a way to use set_one and set_two constants in declaring set_all ?

Something like this:

const std::set<int> set_all = set_one + set_two; // this does not compile, of course!
  1. All objects are strictly constants.
  2. There are no overlapping values in both source sets, so uniqueness will not be an issue.
  3. I know how to merge sets in runtime, this is not what I am looking for.
  4. I am really trying to avoid resorting to macros like this:
#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 };

You can pack them into a lambda and call it immediately (ie 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!

However, if you have the sets in the global scope(like @Kevin mentioned) , you should use the lambda which takes the two sets as arguments

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

or simply

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!

I know how to merge sets in runtime, this is not what I am looking for.

No , You can not create the std::set at compile time as it uses dynamic allocation . Therefore, everything happens at run-time. Even the above lambda.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM