What Would a Std::Map Extended Initializer List Look Like

What would a std::map extended initializer list look like?

It exists and works well:

std::map <int, std::string>  x
{
std::make_pair (42, "foo"),
std::make_pair (3, "bar")
};

Remember that value type of a map is pair <const key_type, mapped_type>, so you basically need a list of pairs with of the same or convertible types.

With unified initialization with std::pair, the code becomes even simpler

std::map <int, std::string> x { 
{ 42, "foo" },
{ 3, "bar" }
};

How can I initialize a std::map with comparison lambda by using an initializer list?

The constructor which takes an initializer list and a comparator is the following:

map( std::initializer_list<value_type> init,
const Compare& comp = Compare(),
const Allocator& alloc = Allocator() );

So you should write:

auto comp = [](int a, int b) { return b < a; };
std::map<int, int, decltype(comp)> m{{{5, 6}, {3, 4}, {1, 2}}, comp};

Why is this considered an extended initializer list?

Pre C++11 (and possibly C99) you can only initialize a POD at creation, not at arbitrary runtime points, which is what you're attempting here (assignment from an initializer list).

You can make a null_foo though:

int main()
{
const foo null_foo = {0, 0, 0};
std::vector<foo> v(1);
v[0] = null_foo;
return 0;
}

Is there any way to append initializer list -- std::initializer_liststd::pairstd::string, std::string?

The length of a std::initializer_list cannot be chosen dynamically at runtime and list's length here is not a compile-time usable property.

std::initializer_list is the wrong tool for this. It should only be used as parameters to functions or implicitly in e.g. a range-for loop. In any case only directly to store a {/*...*/} braced-initializer-list temporarily to be processed further e.g. into a proper container to copy elements from.

If you need a sequence container with runtime-determined dimensions, use std::vector instead. Elements can be added to it with e.g. push_back/emplace_back/insert/emplace member functions and it has a constructor taking an iterator range.

Initializer list of std::pairvectorint, double

You are using an extended initializer list (std::initializer_list) which is available since C++11.

For the gcc 5.4.0 compiler, you need to compile it with C++11 flag:

$ g++ main.cpp -std=c++11

https://gcc.godbolt.org/z/SHzREE

Can lifetime of objects in a initializer list be extended?

This is undefined behaviour.

In your case initializer_list refers to temporary array const double[3], the lifetime of this array is described as below:

ref
The underlying array is not guaranteed to exist after the lifetime of
the original initializer list object has ended. [until c++14]

The lifetime of the underlying array is the same as any other
temporary object [since c++14]

and

ref All temporary objects are destroyed as the last step in evaluating the
full-expression

so in your case when constructor of A is called, temporary array with 3 doubles is created, then you are taking address of elements of temporary array and when constructor ends temporary array is destroyed (in this case the full expression is the call of ctor), so as a result p is dangling poiner.



Related Topics



Leave a reply



Submit