guevara / read-it-later

read it later
232 stars 0 forks source link

How to emulate C array initialization "int arr[] = { e1 e2 e3 ... }" behaviour with std::array? #11898

Open guevara opened 1 week ago

guevara commented 1 week ago

How to emulate C array initialization "int arr[] = { e1, e2, e3, ... }" behaviour with std::array?

https://ift.tt/zAR5DuG



(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.







via Stack Overflow

November 20, 2024 at 09:11AM