Рассмотрим следующий класс mypair
(я не уверен, что это лучший способ сделать что-то, но, похоже, он работает):
#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)
В ответе , когда агрегатная инициализация действительна в C ++ 11 , говорится, что мы можем исключить копии / перемещения, выполняя агрегатную инициализацию.
Следовательно, мы можем построить mypair
s, используя MAKE_PAIR
без необходимости выполнения каких-либо действий или копий.
Я хотел бы обобщить MAKE_PAIR
до MAKE_TUPLE
, то есть принять любое количество аргументов.
Требования (как с MAKE_PAIR
):
(1) Типы выводятся.
(2) Ходы / копии исключаются при построении из временных (то есть строительство происходит на месте).
Существующие библиотечные решения (например, Boost) будут хорошими, хотя я бы предпочел что-то, что принимает ссылки на rvalue. Или просто код здесь тоже отлично, или смесь двух.
Если это вообще возможно, мне бы хотелось, чтобы он оптимизировал пустые элементы, в то время как все еще не допускаются перемещения / вызовы конструктора копирования, но у меня такое чувство, что он требует слишком много.