How to initializing a const set with list of values?
I want to initialize in the preambulum, so I dont want to define and initialize an array before initializing the set. I want to do this in one row, if it is possible.
How to initializing a const set with list of values?
I want to initialize in the preambulum, so I dont want to define and initialize an array before initializing the set. I want to do this in one row, if it is possible.
In modern C++ (C++11 and later), you can initialize a const std::set directly with a braced list. No helper macros, arrays, or temporary containers needed.
#include <set>
const std::set<int> ids{100, 400, 200, 300, 500}; // one line A few tips to make this robust:
{1,2,2,3} becomes {1,2,3}.const std::set<int, std::greater<int>> desc{1, 3, 2}; // elements kept in 3,2,1 const std::set s{1, 2, 3}; // deduces std::set<int> If you need a single definition that is safely initialized exactly once and you care about startup order, wrap it in a function-local static:
const std::set<int>& allowedIds() {
static const std::set<int> s{10, 20, 30};
return s; // thread-safe since C++11
} The approaches shown by and were clever workarounds before brace-init was widely available. Today, prefer the brace-initializer for clarity and zero extra machinery. One last gotcha: if you are storing text, avoid set<const char*> (it orders by pointer value). Use set<std::string> instead:
const std::set<std::string> names{"alice", "bob", "carol"}; That should give you a clean, one-line, in-place initialization that stays const.
Jump to Post— m4ster_r0shi 142Maybe not the best way to do it, but it most certainly is an option:
#include <iostream> #include <set> template <class T> struct SetMaker { std::set<T> data; SetMaker & operator << (const T & element) { data.insert(element); return *this; } SetMaker & operator , (const T & …
Maybe not the best way to do it, but it most certainly is an option:
#include <iostream>
#include <set>
template <class T>
struct SetMaker
{
std::set<T> data;
SetMaker & operator << (const T & element)
{ data.insert(element); return *this; }
SetMaker & operator , (const T & element)
{ data.insert(element); return *this; }
};
#define MAKE_SET_1(T, x1) (SetMaker<T>() << x1).data
#define MAKE_SET_2(T, x1, x2) (SetMaker<T>() << x1, x2).data
#define MAKE_SET_3(T, x1, x2, x3) (SetMaker<T>() << x1, x2, x3).data
#define MAKE_SET_4(T, x1, x2, x3, x4) (SetMaker<T>() << x1, x2, x3, x4).data
#define MAKE_SET_5(T, x1, x2, x3, x4, x5) (SetMaker<T>() << x1, x2, x3, x4, x5).data
// etc...
int main()
{
const std::set<int> my_set(MAKE_SET_5(int, 100, 400, 200, 300, 500));
std::set<int>::const_iterator cur_it = my_set.begin();
std::set<int>::const_iterator end_it = my_set.end();
while (cur_it != end_it) { std::cout << *cur_it << " "; ++cur_it; }
std::cout << "\n(hit enter to quit...)"; std::cin.get();
return 0;
} Boost.Assignment could help too -> http://www.boost.org/doc/libs/1_46_1/libs/assign/doc/index.html
Forget the above. Let's do it the boost way:
#include <iostream>
#include <vector>
#include <list>
#include <set>
template <class T>
struct ListMaker
{
std::list<T> data;
ListMaker & operator ()(const T & element) { data.push_back(element); return *this; }
template <class Container>
operator Container() { return Container(data.begin(), data.end()); }
};
template <class T>
ListMaker<T> list_of(const T & element) { return ListMaker<T>()(element); }
template <class Container>
void print_container(const Container & c)
{
typename Container::const_iterator cur_it = c.begin();
typename Container::const_iterator end_it = c.end();
while (cur_it != end_it) { std::cout << *cur_it << " "; ++cur_it; }
std::cout << std::endl;
}
int main()
{
const std::vector<int> my_vector = list_of(10)(9)(8)(7)(6)(5)(4)(3)(2)(1);
const std::set<int> my_set = list_of(10)(9)(8)(7)(6)(5)(4)(3)(2)(1);
print_container(my_vector);
print_container(my_set);
std::cout << "\n(hit enter to quit...)"; std::cin.get();
return 0;
} There's a lot of copying involved, but the interface is way cleaner.
Peeking at Boost.Assignment source code could still be useful though.
Using a trick I borrowed from http://www.daniweb.com/software-development/cpp/threads/41594, I did the following:
#include <iostream>
#include <set>
using namespace std;
template <typename T, int N>
char (&array(T(&)[N]))[N];
int init[] = {1, 2, 3, 4, 5, 6, 7, 8, 9 };
set<int> myInts ( init, init + sizeof array ( init ) );
int main()
{
set<int>::iterator it = myInts.begin();
while ( it != myInts.end() ) {
cout << *it << endl;
++it;
}
} Not sure if this is what you want.
-lou
We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.