(Note: This question is about not having to specify the number of elements and still allow nested types to be directly initialized.)
This question discusses the uses left for a C array like int arr[20];
. On his answer, @James Kanze shows one of the last strongholds of C arrays, it's unique initialization characteristics:
int arr[] = { 1, 3, 3, 7, 0, 4, 2, 0, 3, 1, 4, 1, 5, 9 };
We don't have to specify the number of elements, hooray! Now iterate over it with the C++11 functions std::begin
and std::end
from <iterator>
(or your own variants) and you never need to even think of its size.
Now, are there any (possibly TMP) ways to achieve the same with std::array
? Use of macros allowed to make it look nicer. :)
??? std_array = { "here", "be", "elements" };
Edit: Intermediate version, compiled from various answers, looks like this:
#include <array>
#include <utility>
template<class T, class... Tail, class Elem = typename std::decay<T>::type>
std::array<Elem,1+sizeof...(Tail)> make_array(T&& head, Tail&&... values)
{
return { std::forward<T>(head), std::forward<Tail>(values)... };
}
// in code
auto std_array = make_array(1,2,3,4,5);
And employs all kind of cool C++11 stuff:
- Variadic Templates
sizeof...
- rvalue references
- perfect forwarding
std::array
, of course- uniform initialization
- omitting the return type with uniform initialization
- type inference (
auto
)
And an example can be found here.
However, as @Johannes points out in the comment on @Xaade's answer, you can't initialize nested types with such a function. Example:
struct A{ int a; int b; };
// C syntax
A arr[] = { {1,2}, {3,4} };
// using std::array
??? std_array = { {1,2}, {3,4} };
Also, the number of initializers is limited to the number of function and template arguments supported by the implementation.
{ { 1, 2 }, { 3, 4 } }
. More work is needed to make that work. – Stericinterface
as a problem in the language. Why do you care that the base classes are fully abstract or not? They should be what the semantics for that type require, and in many cases that is not fully abstract, consider for example, the NVI idiom: virtual methods not being part of the public interface pretty much rules out the possibility of an all pure virtual functions class --if you want any functionality at all. – Dermatosisstd::array<int> x{1,2,3,4,5};
. More importantly, though, imagine you have a class with a member of type std::array. How do you initialize that member in the constructor's initializer list (say to a definite value like {1,2,3})? – Upstatestd::array<int, 5> x {1,2,3,4,5}
. That line works on its own, but I can't get it to work ifx
is a class member and I want to initialize this in the constructor's initializer list (GCC 4.4). – Upstatedecay
is needed, orint x=3; auto arr=make_array(x);
makes astd::array<int&,1>
– OgTMP
in your question? – Decarbonate