auto with array

103 views
Skip to first unread message

Sarang

unread,
May 4, 2011, 4:13:25 PM5/4/11
to

I was trying out auto keyword support with C++0x, it works great and
is very nifty feature, however I am not sure why it is not allowed
with arrays.
I am using VS 2010 SP1 and the code is:

// cannot deduce an array of elements with auto
// fails to compile with error message:
// "the element type of an array cannot be a type that contains
'auto'"
auto arr1[] = {'a','b','c'};

// too many initializers
auto arr2 = {'a','b','c'};

// cannot deduce type for auto* from char
// cannot convert from char to int*
auto* arr3 = {'a','b','c'};

It would be great if some one could enlighten me why are all these
initialization illegal.
Thanks!

Sarang


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Daniel Krügler

unread,
May 5, 2011, 9:34:24 AM5/5/11
to

Am 04.05.2011 22:13, schrieb Sarang:
>
> I was trying out auto keyword support with C++0x, it works great and
> is very nifty feature, however I am not sure why it is not allowed
> with arrays.
> I am using VS 2010 SP1 and the code is:
>
> // cannot deduce an array of elements with auto
> // fails to compile with error message:
> // "the element type of an array cannot be a type that contains
> 'auto'"
> auto arr1[] = {'a','b','c'};
>
> // too many initializers
> auto arr2 = {'a','b','c'};
>
> // cannot deduce type for auto* from char
> // cannot convert from char to int*
> auto* arr3 = {'a','b','c'};
>
> It would be great if some one could enlighten me why are all these
> initialization illegal.

The reason for this is, that your initializer in all these examples is a
braced-init-list (i.e. the {'a','b','c'} thingee), which is *not* an
expression. For braced-init-lists, the compiler is supposed to deduce
it as some instance std::initializer_list<T> and there is no conversion
from std::initializer_list<T> to any array. But since such an
std::initializer_list<T> object is always backed by an implicit array,
it is just as simple that you should write

auto arr_list = {'a','b','c'};

which is deduced to std::initializer_list<char>. Given such an object,
you have all data available that you would have from an array (it has
a size() function, and a begin()/end() pair).

There is only one disadvantage as of the current state: The size()
function cannot yet be evaluated as a constant expression. I hope that
this constraint can be solved in the future by making this function
required to be a constexpr function.

HTH & Greetings from Bremen,

Daniel Krügler

SG

unread,
May 5, 2011, 5:51:18 PM5/5/11
to

On 4 Mai, 22:13, Sarang wrote:
> I was trying out auto keyword support with C++0x, it works great and
> is very nifty feature, however I am not sure why it is not allowed
> with arrays.
> I am using VS 2010 SP1 and the code is:
>
> // cannot deduce an array of elements with auto
> // fails to compile with error message:
> // "the element type of an array cannot be a type that contains
> 'auto'"
> auto arr1[] = {'a','b','c'};

auto generally only works for expressions. {'a','b','c'} is not an
expression. It's an initializer list. But for the purpose of type
deduction for auto (and for auto only, NOT for other function
templates' arguments) this initializer list is considered to be a
std::initializer_list<char> according to a special rule (if I remember
correctly). Since there is no T so that T[] "matches"
std::initializer_list<char>, this code fails to compile.

> // too many initializers
> auto arr2 = {'a','b','c'};

Weird. As far as I know, this is supposed to work and decltype(arr2)
is supposed to be std::initializer_list<char> in this case. Maybe it
has not yet been implemented in MSVC++.

> // cannot deduce type for auto* from char
> // cannot convert from char to int*
> auto* arr3 = {'a','b','c'};

See comment for the first example.


Cheers!
SG

Jeffrey Schwab

unread,
May 5, 2011, 11:41:52 PM5/5/11
to
On Thursday, May 5, 2011 5:51:18 PM UTC-4, SG wrote:
> On 4 Mai, 22:13, Sarang wrote:

> > // too many initializers
> > auto arr2 = {'a','b','c'};
>
> Weird. As far as I know, this is supposed to work and decltype(arr2)
> is supposed to be std::initializer_list<char> in this case. Maybe it
> has not yet been implemented in MSVC++.

$ cat main.cpp #include <algorithm>
#include <initializer_list>
#include <iostream>
#include <iterator>

int main() {

/* No problem in GCC 4.6.0. */
auto const cs = {'a', 'b', 'c'};

/* OK */
for (char const c : cs) {
std::cout << c;
}
std::cout << std::endl;

/* Also OK */
std::copy(cs.begin(), cs.end(), std::ostream_iterator<char>( std::cout ));
std::cout << std::endl;
}
$ make
/home/jeff/opt/gcc/bin/g++ -std=c++0x -pedantic -Wall -I. -Wno-unused-variable -Wno-unused-but-set-variable -o main.o -c main.cpp
./m/home/jeff/opt/gcc/bin/g++ -o main main.o
$ ./main
abc
abc

Reply all
Reply to author
Forward
0 new messages