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.