How-To Initialize 'Const Std::Vector<T>' Like a C Array

how-to initialize 'const std::vector T ' like a c array

For C++11:

vector<int> luggage_combo = { 1, 2, 3, 4, 5 };

Original answer:

You would either have to wait for C++0x or use something like Boost.Assign to do that.

e.g.:

#include <boost/assign/std/vector.hpp>
using namespace boost::assign; // bring 'operator+=()' into scope

vector<int> v;
v += 1,2,3,4,5;

Initializing a std::array with a constant value

With std::index_sequence, you might do:

namespace detail
{
template <typename T, std::size_t ... Is>
constexpr std::array<T, sizeof...(Is)>
create_array(T value, std::index_sequence<Is...>)
{
// cast Is to void to remove the warning: unused value
return {{(static_cast<void>(Is), value)...}};
}
}

template <std::size_t N, typename T>
constexpr std::array<T, N> create_array(const T& value)
{
return detail::create_array(value, std::make_index_sequence<N>());
}

With usage

auto a = create_array<10 /*, int*/>(7); // auto is std::array<int, 10>

Which, contrary to std::fill solution, handle non default constructible types.

What is the easiest way to initialize a std::vector with hardcoded elements?

One method would be to use the array to initialize the vector

static const int arr[] = {16,2,77,29};
vector<int> vec (arr, arr + sizeof(arr) / sizeof(arr[0]) );

Initialize a vector array of strings

Sort of:

class some_class {
static std::vector<std::string> v; // declaration
};

const char *vinit[] = {"one", "two", "three"};

std::vector<std::string> some_class::v(vinit, end(vinit)); // definition

end is just so I don't have to write vinit+3 and keep it up to date if the length changes later. Define it as:

template<typename T, size_t N>
T * end(T (&ra)[N]) {
return ra + N;
}

Cannot initialize a vector of const char*/string array with an initializer-list on declaration

It fails to compile because std::vector requires its T to be CopyAssignable. No matter its RHS, this statement wouldn't not compile:

vector<const char*[3]> v = { { "a", "b", "c" } }; // Error

just as this wouldn't compile either:

std::vector<const char*[3]> v;
const char* charPtrArr[3] { "a", "b", "c" };
v.push_back(charPtrArr); // Error

This is just a particular case of the fact that C-style arrays are not assignable, demonstrated in code directly by using static_assert:

static_assert(std::is_copy_assignable<const char*[3]>()); // Error

or more generally I guess:

static_assert(std::is_copy_assignable<int[]>()); // Error

If you really wanted a std::vector of arrays of size 3 holding char pointers, then this is the error-free C++11 way to go about it:

vector<array<const char*, 3>> v = { { "a", "b", "c" }, { "d", "e", "f"} };

Cannot create constexpr std::vector

AFAIK The initlializer_list constructor of std::vector<> is not declared constexpr.

Initialize a C++ (11) std::vector with the content of another one and extra elements

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.

How to initialize std::vector from C-style array?

Don't forget that you can treat pointers as iterators:

w_.assign(w, w + len);

C++11: Correct std::array initialization?

This is the bare implementation of std::array:

template<typename T, std::size_t N>
struct array {
T __array_impl[N];
};

It's an aggregate struct whose only data member is a traditional array, such that the inner {} is used to initialize the inner array.

Brace elision is allowed in certain cases with aggregate initialization (but usually not recommended) and so only one brace can be used in this case. See here: C++ vector of arrays

no match for operator '=' (std::array T, 3 and std::initializer_list T )

Why can't I initialize std::array with initializer list in such a way?

Braced-init-list and std::initializer_list are not the same thing. (Even std::initializer_list could be constructed from braced-init-list.) std::array is an aggregate and could be aggregate-initialized or assigned by braced-init-list as

std::array<int, 3> a = {1, 2, 3};
a = {4, 5, 6}; // convert {4, 5, 6} to std::array then assign to a

Note that both {1, 2, 3} and {4, 5, 6} are braced-init-list but not std::initializer_list.

std::array can't be initialized (or assigned) from an std::initializer_list; its constructors and assignment operator are implicitly-defined and doesn't have such constructor or assignment operator taking std::initializer_list.

std::initializer_list<int> l = {1, 2, 3};
std::array<int, 3> a = l; // doesn't work
a = l; // doesn't work


Related Topics



Leave a reply



Submit