// 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! ]
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
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
> > // 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