I need an "elegant" way of initializing a vector in the declaration phase with the content of another one and a few extra elements.
What I want to solve is:
Let's consider the following (example) declaration with initialization:
const std::vector<std::string> c90_types = {
"char",
"signed char",
"unsigned char",
"short",
"unsigned short",
"int",
"unsigned int",
"long",
"unsigned long",
"float",
"double",
"long double"
};
const std::vector<std::string> c99_types = {
"char",
"signed char",
"unsigned char",
"short",
"unsigned short",
"int",
"unsigned int",
"long",
"unsigned long",
"float",
"double",
"long double",
"long long",
"unsigned long long",
"intmax_t",
"uintmax_t"
};
as you can see c99_types
has a subset which is exactly c90_types
. I want to avoid the situation where I need to change the subset and then change manually the "superset" too, just to avoid the extra step that might introduce bugs :)
As a side note, I don't want to write code like:
second.insert(second.begin(), first.begin(), first.end());
second.push_back(something);
Any good and clean solutions to this?
Begin Initialize a vector v1 with its elements. Declare another vector v2 and copying elements of first vector to second vector using constructor method and they are deeply copied. Print the elements of v1. Print the elements of v2.
Begin Declare v of vector type. Call push_back() function to insert values into vector v. Print “Vector elements:”. for (int a : v) print all the elements of variable a.
There is a trick called "I want to initialize a const variable with something elaborate." that became possible with C++11, shamelessly stolen from Javascript.
const std::vector<std::string> c90_types = {
"char",
// and so on, and so forth....
};
const std::vector<std::string> c99_types = ([&](){
const auto additional_types = { // initializer_list<const char *>, but it does not matter.
"long long",
"unsigned long long",
"intmax_t",
"uintmax_t"
};
std::vector<std::string> vec{c90_types};
vec.insert(vec.end(), additional_types.begin(), additional_types.end());
return vec;
})();
Pack your initialization logic into an unnamed lambda, and call it right away, copy-initializing your const variable.
vec
is moved, not copied.
You could define the biggest vector (here that would be c99_types) first, and then construct the others with iterators from the largest one.
Here is an example :
const vector<int> a{1,2,3,4};
const vector<int> b{begin(a), begin(a)+2}; // b is {1,2}
So you could write:
const std::vector<std::string> c99_types = {
"char",
"signed char",
"unsigned char",
"short",
"unsigned short",
"int",
"unsigned int",
"long",
"unsigned long",
"float",
"double",
"long double",
"long long",
"unsigned long long",
"intmax_t",
"uintmax_t"
};
const std::vector<std::string> c90_types{begin(c99_types), begin(c99_types)+12};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With