Reputation: 3593
I have a ctor declared like this:
template<typename... Coords>
MyClass<T>(vector<T> values, Coords... coords) { /* code */ }
I want it to look like this:
template<typename... Coords>
MyClass<T>(Coords... coords, vector<T> values) { /* code */ }
but the standard requires the variadic argument to be the last. If I write something like
template<typename... Args>
MyClass<T>(Args... coordsThenValues) { /* code */ }
how would I split coordsThenValues
into an all-but-last parameter pack Coords... coords
and the last parameter vector<T> values
?
Upvotes: 4
Views: 1169
Reputation: 275405
Do you like tuples?
How do you like forward as tuple?
struct foo {
template<class...Ts>
foo(Ts&&...ts):
foo(
magic<0>{}, // sent it to the right ctor
std::index_sequence< sizeof...(ts)-1 >{}, // the last shall be first
std::make_index_sequence<sizeof...(ts)-1>{}, // the first shall be last
std::forward_as_tuple(std::forward<Ts>(ts)...) // bundled args
)
{}
private:
template<size_t>
struct magic {};
template<size_t...I0s, size_t...I1s, class...Ts>
foo(
magic<0>, // tag
std::index_sequence<I0s...>, // first args
std::index_sequence<I1s...>, // last args
std::tuple<Ts...> args // all args
):
foo(
magic<1>{}, // dispatch to another tagged ctor
std::get<I0s>(std::move(args))..., // get first args
std::get<I1s>(std::move(args))... // and last args
)
{}
// this ctor gets the args in an easier to understand order:
template<class...Coords>
foo(magic<1>, std::vector<T> values, Coords...coords) {
}
};
here the public ctor packs up the arguments into a tuple of references (possibly l, possibly r). It also gets two sets of indexes.
It then sends it to magic<0>
ctor, which shuffles the arguments around so that the last one is first (assuming the indexes are right).
The magic<1>
ctor gets the vector first, then the coords.
Basically I shuffled the arguments around so the last one became first.
magic
just exists to make me not have to think much about overload resolution, and make which ctor I'm forwarding to explicit. It would probably work without it, but I like tagging when I'm doing something crazy with ctor forwarding.
Upvotes: 6