Consider the following mypair
class (I'm not sure if this is the best way to do things, but it seems to work):
#include <iostream>
struct A
{
A() {}
A(const A&) { std::cout << "Copy" << std::endl; }
A(A&&) { std::cout << "Move" << std::endl; }
std::string s;
};
template <class T0, class T1>
struct mypair
{
T0 x0;
T1 x1;
};
template <class T0, class T1, int N = -1>
struct get_class {};
template<class T0, class T1>
struct get_class<T0, T1, 0>
{
static T0& get_func(mypair<T0, T1>& x) { return x.x0; }
static const T0& get_func(const mypair<T0, T1>& x) { return x.x0; }
static T0&& get_func(mypair<T0, T1>&& x) { return std::move(x.x0); }
};
template<class T0, class T1>
struct get_class<T0, T1, 1>
{
static T1& get_func(mypair<T0, T1>& x) { return x.x1; }
static const T1& get_func(const mypair<T0, T1>& x) { return x.x1; }
static T1&& get_func(mypair<T0, T1>&& x) { return std::move(x.x1); }
};
template <int N, class T0, class T1>
auto get(mypair<T0, T1>& x) -> decltype(get_class<T0,T1,N>::get_func(x))
{ return get_class<T0,T1,N>::get_func(x); }
#define MAKE_PAIR(x1, x2) mypair<decltype(x1), decltype(x2)>{x1, x2}
int main()
{
auto x = MAKE_PAIR(A(), A());
get<0>(x);
get<1>(x);
}
(ideone link)
The answer when is aggregate initialization valid in C++11 says we can elide copies/moves by doing aggregate initialization.
Hence, we can construct mypair
s using MAKE_PAIR
without the need to perform any moves or copies.
I would like to generalize MAKE_PAIR
to MAKE_TUPLE
, i.e. take any number of arguments.
Requirements are (as with MAKE_PAIR
):
(1) Types are inferred.
(2) Moves/copies are elided when constructing from temporaries (i.e. construction happens in place).
Existing library solutions (e.g. Boost) will be fine, though I'd prefer something which accepts rvalue references. Or just code here is great also, or a mix of the two.
If it is at all possible, I'd like it if it optimized out empty members whilst still eliding moves/copy constructor calls, but I have a feeling that is asking too much.
There is already such a feature in the C++0x Standard Library- a std::make_tuple
. Even if you get bored, you can make your own.
template<typename... T> std::tuple<T...> make_tuple(T...&& refs) {
return std::tuple<T...> { std::forward<T>(refs)... };
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With