How can I use std::make_tuple if the execution order of the constructors is important?
For example I guess the execution order of the constructor of class A and the
The trivial solution is not to use std::make_tuple(...) in the first place but to construct a std::tuple<...> directly: The order in which constructors for the members are called is well defined:
template
std::istream& dummy(std::istream& in) {
return in;
}
template
std::tuple parse(std::istream& in) {
return std::tuple(dummy(in)...);
}
The function template dummy is only used to have something to expand on. The order is imposed by construction order of the elements in the std::tuple:
template
template
std::tuple::tuple(U...&& arg)
: members_(std::forward(arg)...) { // NOTE: pseudo code - the real code is
} // somewhat more complex
Following the discussion below and Xeo's comment it seems that a better alternative is to use
template
std::tuple parse(std::istream& in) {
return std::tuple{ T(in)... };
}
The use of brace initialization works because the order of evaluation of the arguments in a brace initializer list is the order in which they appear. The semantics of T{...} are described in 12.6.1 [class.explicit.init] paragraph 2 stating that it follows the rules of list initialization semantics (note: this has nothing to do with std::initializer_list which only works with homogenous types). The ordering constraint is in 8.5.4 [dcl.init.list] paragraph 4.