首页 > 解决方案 > 在声明中合并两个常量 `std::set`s(不在运行时)

问题描述

我试图优雅地声明一个常量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_oneset_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 };

标签: c++c++11data-structuresc++-standard-librarystdset

解决方案


您可以将它们打包成一个 lambda 并立即调用它(即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提到的),您应该使用将这两个集合作为参数的 lambda

#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在编译时创建,因为它使用动态分配。因此,一切都发生在运行时。即使是上面的 lambda。


推荐阅读