Array of initializer lists?

J

Juha Nieminen

I'm trying to do this:

auto values[] = { { 1, 2, 3 }, { 4, 5, 6 } };

but gcc 4.6 is giving me the error:

error: unable to deduce 'std::initializer_list<auto>' from '{{1, 2, 3}, {4, 5, 6}}'

If I make a small change, it doesn't help:

auto values = { { 1, 2, 3 }, { 4, 5, 6 } };

(the same error is issued.)

Is this because the above code is invalid, or because gcc 4.6 doesn't
yet work properly with such constructs?

Note that this compiles and works as expected:

auto values = { { 1, 2, 3 } };
 
V

Victor Bazarov

I'm trying to do this:

auto values[] = { { 1, 2, 3 }, { 4, 5, 6 } };

but gcc 4.6 is giving me the error:

error: unable to deduce 'std::initializer_list<auto>' from '{{1, 2, 3}, {4, 5, 6}}'

If I make a small change, it doesn't help:

auto values = { { 1, 2, 3 }, { 4, 5, 6 } };

(the same error is issued.)

Is this because the above code is invalid, or because gcc 4.6 doesn't
yet work properly with such constructs?

Note that this compiles and works as expected:

auto values = { { 1, 2, 3 } };

The doubled-up braces are converted into single ones here, so no
surprise that it's OK.

When you supply a brace-enclosed initializer list, the compiler is
supposed to initialize the object with 'initializer_list<blah>', and
nested brace initializers probably call for
'initializer_list<initializer_list<blah>>', which is likely too much for
the compiler to deduce.

V
 
J

Juha Nieminen

Victor Bazarov said:
The doubled-up braces are converted into single ones here, so no
surprise that it's OK.

That does not seem to be the case. There's a difference between
"{ 1, 2, 3 }" and "{ { 1, 2, 3 } }".

For example, this works:

auto values = { 1, 2, 3 };
for(auto& i: values)
std::cout << i << std::endl;

However, this does not:

auto values = { { 1, 2, 3 } };
for(auto& i: values)
std::cout << i << std::endl;

To make it work, it has to be done like:

auto values = { { 1, 2, 3 } };
for(auto& i: values)
for(auto& j: i)
std::cout << j << std::endl;

which makes sense. 'values' is an array (or possibly an initializer list,
I'm not completely sure) containing an initializer list, hence the need
for the double loop.

It would, thus, make sense if one could put more than one initializer
list inside the array, like:

auto values = { { 1, 2, 3 }, { 4, 5, 6 } };
for(auto& i: values)
for(auto& j: i)
std::cout << j << std::endl;

'values' would still be an array of initializer lists; it's just that
in this case it contains two of them rather than one. However, as said,
gcc 4.6 issues an error on the first line.
 
J

Johannes Schaub

Juha said:
I'm trying to do this:

auto values[] = { { 1, 2, 3 }, { 4, 5, 6 } };

but gcc 4.6 is giving me the error:

error: unable to deduce 'std::initializer_list<auto>' from '{{1, 2, 3},
{4, 5, 6}}'

If I make a small change, it doesn't help:

auto values = { { 1, 2, 3 }, { 4, 5, 6 } };

(the same error is issued.)

Is this because the above code is invalid, or because gcc 4.6 doesn't
yet work properly with such constructs?

Note that this compiles and works as expected:

auto values = { { 1, 2, 3 } };

I think you want to read http://stackoverflow.com/q/7699963/34509 . Note
that "auto x = { ... }" is no different from transforming "auto x = { ... }"
to the following

template<typename T> void trans(initializer_list<T>);
trans({...});

"initializer_list<T>", with the deduced T (as described in the answer on
that stackoverflow question) will be the type of the auto variable "x".
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,051
Latest member
CarleyMcCr

Latest Threads

Top