I am working on a petty (pretty) printer for PODs, STLs and Composite Types like Arrays. While doing so, I was also fiddling with Initialization Lists and came across the following declaration
std::vector<double[3]> arr{ { 10, 11, 12 }, { 20, 21, 22 } };
It seems both VC2013 and G++ 4.8 is not quite happy and issues a consistent error message which in either case is not quite helpful to me
For VC++: error C3074: an array can only be initialized with an initialize-list
For G++ 4.8: error: array must be initialized with a brace-enclosed initialize
So either Initialization lists cannot be used here or my syntax is quite not right?
On a similar front, the following syntax seems to be valid
std::vector<std::array<int, 3>> arr{ { 10, 11, 12 }, { 20, 21, 22 } };
What is the possible problem with my initialization list?
std::array
instead of C type arrays but I am just experimenting. Reading the current C++1y draft standard.
From before Table 99:
T is EmplaceConstructible into X from args , for zero or more arguments args , means that the following expression is well-formed: allocator_traits::construct(m, p, args)
Table 100:
X(il); | Equivalent to | X(il.begin(), il.end());
--------------------+---------------------+--------------------------------
X(i, j); | | Requires:
X a(i, j); | | T shall be EmplaceConstructible
| into X from *i.
So std::vector<double[3]> v{ {1,2,3}, {4,5,6} };
is valid iff double[3]
is EmplaceConstructible
from {1,2,3}
as an element of an initializer list being passed to a std::vector<double[3]>
.
There is a clause about forward iterators as well, but that is no problem (as std::initialzier_list
iterators are forward iterators).
std::vector<T>
takes an std::initializer_list<T>
parameter.
So std::initializer_list<double[3]>
is the candidate list.
First, std::initializer_list<double[3]> x = {{1.0, 2.0, 3.0}};
fails to compile in gcc. But suppose that is a bug in gcc.
Second, ::new (nullptr) double[3](std::initializer_list<double>{1.0, 2.0, 3.0});
placement new, which EmplaceConstructable
reduces to in the lack of a suitable construct
override, fails to compile.
So double[3]
is not EmplaceConstruble
from a std::initalizer_list<double>
nor from a double[3]
nor anything else (as the error occurs because I used a bracket, not because of what was in the brackets, in the placement new), unless the allocator does magic I am not aware of to avoid the placement new.
Thus your code violates the current draft standard, and probably C++11, and certainly C++03 (which had stricter requirements on containers).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With