Reputation: 9432
Is it possible to construct such a tuple
somehow?
#include <tuple>
struct A
{
A() = default;
A(const A&) = delete;
A(A&&) = delete;
};
auto generate()
{
// Funktion which constructs a tuple on one line...
return std::make_tuple(A{},A{});
}
int main()
{
auto t = generate();
}
Is this possible in C++14 and is this possible in C++17 which forces Return-Value-Optimization (unnamed prvalue return expression)??
Upvotes: 3
Views: 567
Reputation: 275500
std::tuple<A,A> generate() { return {}; }
If you need to non-default construct A
:
template<class U, class F>
struct maker_t{ operator U(){ return f(); } F f; };
template<class U, class F>
maker_t<U,std::decay_t<F>> maker(F&& f){ return {std::forward<F>(f)}; }
Now you can:
std::tuple<A,A> generate() {
return {
maker<A>( []{ return A{}; } ),
maker<A>( []{ return A{}; } )
};
}
where those lambdas can do anything that returns an A
.
Upvotes: 2
Reputation: 473537
tuple
's constructor that initializes the objects from arguments of the exact same types as the tuple
's template parameters requires that the types are copy-constructible. However, if all of the types are default-constructible, then you can do that. So you could just have generate
issue a return tuple<A, A>{};
. This works in C++17.
If you want to initialize them with a value, then you can use the tuple
constructor that uses explicit conversion from a sequence of types that aren't the same as the tuple
parameters. There, you can use C++17 guaranteed copy elision, but only if the source types use an operator Type()
overload and follow the rules of guaranteed elision.
Upvotes: 3