Current status of std::make_array
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
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.
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.