Home > Mobile >  std::make_from_tuple doesn't compile without constructor
std::make_from_tuple doesn't compile without constructor

Time:11-19

I have a simple struct:

struct A
{
    int a;
    int b;
    int c;
    
    // A(int a, int b, int c) : a{a}, b{b}, c{c} { }
};

The constructor is commented for now. I am trying to create object of type A in a such way:

auto t = std::make_tuple(1, 2, 3);
A a = std::make_from_tuple<A>(std::move(t));

but it doesn't compile. MSVC gives a message: <function-style-cast>: cannot convert from initializer_list to _Ty. After I uncomment the constructor of struct A, it starts working.

The question is: why std::make_from_tuple() requires a user-defined constructor instead of default one?

CodePudding user response:

If you look closely at the implementation of make_from_tuple in the standard:

namespace std {
  template<class T, class Tuple, size_t... I>
    requires is_constructible_v<T, decltype(get<I>(declval<Tuple>()))...>
  constexpr T make-from-tuple-impl(Tuple&& t, index_sequence<I...>) {   
    return T(get<I>(std::forward<Tuple>(t))...);
  }
}

It uses parentheses (()) to initialize T with direct initialization. Since A is an aggregate, it cannot use parentheses for initialization in C 17, and can only use curly braces ({}) for list initialization.

It is worth noting that P0960 makes it possible to use parentheses to initialize aggregates in C 20, so your code is well-formed in C 20.

  • Related