A convenient way creating a std::array

Update1: The original title of this post was "A convenient constructor for std::array" but it has brought to my attention that this is a bad name. What it was. Therefore this post describes now a convenient way creating a std::array. Thanks to @jonkalb and @fallingfrombed and @marshall from the C++ slack channel who where the first providing this valuable feedback

Update2: I was not very surprised about the hint, I think by Arne Mertz on cpp slack, that this solution already exists in TR2. This is great, the implementation in TR2 is of course much more advanced than what I have written. Having a place where I can borrow this implementation from is of course my preferred way. I am very aware of the fact that there are many people out there who’s implementation of such functions are in general more advanced and better than my version.

Constructing std::array

I like and use std::array a lot. But every time I used and have to declare one, I thought that’s a bit to much text to write. And why to I have to tell the compiler the type since it’s know because it’s there?

A short example to illustrate what I mean.

std::array<int, 3> ai {1, 2, 3} ;

std::array<double, 3> ad {1.0, 2.0, 3.0} ;

std::array<std::string, 3> as {"a", "b", "c"} ;

You see?

  • Its a bit too much text on the left hand side of the variable name.

  • The 3rd declaration is even questionable if the correct type is used.

Create some syntax sugar

Let’s improve this following the test driven approach.

First some usage code

auto ai = array(1, 2, 3) ;

auto ad = array(1.0, 2.0, 3.0) ;

auto as = array("a", "b", "c") ;

Isn’t this much better? I think it is.

For this to work I need a function that does the dirty work for me.

The function that constructs the array looks like this

template<typename... Args>
std::array<typename std::common_type<Args...>::type, sizeof...(Args)>
array(Args&&... args)
{
  return std::array<typename std::common_type<Args...>::type,
      sizeof...(Args)>{  std::forward<Args>(args)... };
}

And I think, the as from above will have a much better fitting type.

Please note that this may breake code containing a using std::array.
In this case the function should be called something different, like, make_array maybe.

Here the copy and past version

for your favourite online compiler

#include <iostream>
#include <array>

template<typename... Args>
std::array<typename std::common_type<Args...>::type, sizeof...(Args)>
array(Args&&... args)
{
  return std::array<typename std::common_type<Args...>::type,
      sizeof...(Args)>{  std::forward<Args>(args)... };
}

int main()
{
  auto chars = array("a", "b", "c") ;

  for (auto&c  : chars)
    std::cout <<  c << std::endl ;

  for (auto& d : array(1.0, 2.0, 3.0))
    std::cout << d << std::endl ;
}

If you find any mistakes, in the code or in my spelling, please add a comment below, ideas for improvements are also very much welcome.