What is the current status of std::make_array
function proposed here? I cannot find any information about its potential acceptance. According to cppreference.com, it's in the std::experimental
namespace. It's not mentioned at all on C++ compiler support nor on Wikipedia-C++17, Wikipedia-C++20, and C++17 Standard draft.

- 8,540
- 6
- 45
- 76

- 22,196
- 3
- 50
- 93
-
6`std::make_array` is kind of useless since C++17, isn't it? We can now have `std::array arr = { 1, 2, 3, 4, 5 };` without the need to specify type+size. – DeiDei Jun 20 '18 at 07:32
-
2@DeiDei - in C++17 - can we only omit array size? I mean - that can help in doing something like this: `auto a = std::make_array
(1, (float)1.2, 'x')` - where one wants the compiler to just calculate the size - but cannot use deduction guide because types are different (but castable to desired type) – PiotrNycz Jun 20 '18 at 07:46 -
@PiotrNycz - You can't do that with `std::make_array` either. You specified *one type* in the pack. The rest are still deduced and checked against. – StoryTeller - Unslander Monica Jun 20 '18 at 07:49
-
1@StoryTeller In examples (in linked proposal) I see this: `auto a2 = make_array
(2, 3U); // explicit destination type` - so looks - it would be possible? – PiotrNycz Jun 20 '18 at 07:54 -
1@PiotrNycz - The proposal uses `std::common_type`. It will only work if the desired destination type *is* the common type, or a larger type. Your own attempt won't work, since the common type would be `float`, not `int`. – StoryTeller - Unslander Monica Jun 20 '18 at 07:56
-
Which I think goes to show that the proposal is left with some details not ironed out completely. Probably because it was abandoned in favor of the deduction guide. – StoryTeller - Unslander Monica Jun 20 '18 at 07:58
-
@StoryTeller - are you sure - I see this part: `template
constexpr array – PiotrNycz Jun 20 '18 at 07:59make_array(Types&&...);` - `Returns: An array initialized with { std::forward (t))... }.` -
@PiotrNycz - Interesting. I'm not sure how partial ordering should work here. I would have suspected ambiguity. But anyway, even assuming that, the proposal's own example has a vivid `// error: narrowing`, just like the code in your original comment will produce. – StoryTeller - Unslander Monica Jun 20 '18 at 08:03
-
The OP linked an old version of the proposal. – T.C. Jun 20 '18 at 08:03
-
@StoryTeller - ok - but for other input types, that do not "narrow", such utility would be beneficial. It is also quite easy to implement (with different names - make_array, make_array_of_type - the ambiguity is really in this proposal) – PiotrNycz Jun 20 '18 at 08:11
-
1@DeiDei Thanks for pointing this out, didn't know about this possibility in C++17 enabled due to explicit deduction guides. One is learning something new every day with C++ :) – Daniel Langr Jun 20 '18 at 10:16
5 Answers
As @DeiDei writes, C++17 includes template argument deduction for classes, so you can now write:
std::pair p (foo, bar);
std::array arr = { 1, 2, 3, 4, 5 };
and so on. But there are some (somewhat subtle) remaining use cases where make_pair
or make_array
can be useful, and you can read about them in: Usefulness of std::make_pair and std::make_tuple in C++1z
@Ruslan correctly notes in a comment that the above is mostly useful when the type of the elements is "obvious" to the compiler, or made explicit for each element. If you want to explicitly construct elements of some type, the above looks like;
std::array arr = { MyType{1,2}, MyType{3,4}, MyType{5,6}, MyType{7,8} };
which is too wordy; and that's one of the cases where you fall back on:
std::make_array<MyType>{ {1,2}, {3,4}, {5,6}, {7,8} };

- 118,144
- 57
- 340
- 684
-
This is so cool! Didn't know that you can have `std::array`'s template arguments deduced. Thank you! – j00hi Jan 10 '19 at 09:11
-
1This is still not good enough when `value_type` is not builtin: e.g. you have to use `std::array arr={Type{1,3}, Type{7,2}, /*...,*/ Type{32,71}};` instead of what you'd write as `auto arr=std::make_array
({1,3}, {7,2}, /*...,*/ {32,71});`, which would be much shorter for longer arrays. – Ruslan May 22 '21 at 08:54 -
Isn't the remaining use case for `make_array` covered by `std::to_array` where the user can explicitly state the type of the array elements?! – usr1234567 Dec 27 '21 at 09:41
-
1@usr1234567: My answer is from 2018, `std::to_array` is from C++2020... – einpoklum Dec 27 '21 at 09:56
LEWG voted to forward the merge paper for C++20 back in 2016 (this was after the C++17 feature freeze). Its LWG review is on hold at the author's request pending the resolution of LWG issue 2814.

- 133,968
- 17
- 288
- 421
-
Looks like that issue was resolved in 2020. So what's the status now? It might seem it was replaced with `std::to_array` and `std::make_array` was dropped? – Zitrax Jul 20 '23 at 09:35
This answer provided the status of the proposal - however - it is pretty easy to implement in C++17 - at least this part:
[Example:
int i = 1; int& ri = i; auto a1 = make_array(i, ri); // a1 is of type array<int, 2> auto a2 = make_array(i, ri, 42L); // a2 is of type array<long, 3> auto a3 = make_array<long>(i, ri); // a3 is of type array<long, 2> auto a4 = make_array<long>(); // a4 is of type array<long, 0> auto a5 = make_array(); // ill-formed auto a6 = make_array<double>(1, 2); // ill-formed: might narrow –end example]
See:
template <typename Dest=void, typename ...Arg>
constexpr auto make_array(Arg&& ...arg) {
if constexpr (std::is_same<void,Dest>::value)
return std::array<std::common_type_t<std::decay_t<Arg>...>, sizeof...(Arg)>{{ std::forward<Arg>(arg)... }};
else
return std::array<Dest, sizeof...(Arg)>{{ std::forward<Arg>(arg)... }};
}
The proof:
int main() {
int i = 1; int& ri = i;
auto a1 = make_array(i, ri); // a1 is of type array<int, 2>
std::cout << print<decltype(a1)>().get() << std::endl;
auto a2 = make_array(i, ri, 42L); // a2 is of type array<long, 3>
std::cout << print<decltype(a2)>().get() << std::endl;
auto a3 = make_array<long>(i, ri); // a3 is of type array<long, 2>
std::cout << print<decltype(a3)>().get() << std::endl;
auto a4 = make_array<long>(); // a4 is of type array<long, 0>
std::cout << print<decltype(a4)>().get() << std::endl;
// auto a5 = make_array(); // ill-formed
// auto a6 = make_array<double>(1, 2); // ill-formed: might narrow
}
Output:
std::__1::array<int, 2ul>
std::__1::array<long, 3ul>
std::__1::array<long, 2ul>
std::__1::array<long, 0ul>
The last line make_array<double>(1, 2)
produces "narrowing cast" errors - as required in proposal. It can be "improved" by adding static_cast in implementations.
On latest clang - demo.

- 23,099
- 7
- 66
- 112
There is an experimental make_array
now.
https://en.cppreference.com/w/cpp/experimental/make_array
Defined in header
<experimental/array>
template <class D = void, class... Types> constexpr std::array<VT /* see below */, sizeof...(Types)> make_array(Types&&... t);
(library fundamentals TS v2)

- 14,261
- 4
- 67
- 118
From C++20 we can use std::to_array, like so:
auto arr = std::to_array<CustomDataType>({a, b, c});
So long as a, b, c
are each convertible to CustomDataType
.

- 2,603
- 2
- 18
- 35