元组聚合构造推断类型和elides移动/复制构造函数调用?

Cli*_*ton 6 c++ optimization tuples aggregate c++11

考虑以下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);
}
Run Code Online (Sandbox Code Playgroud)

(意思链接)

在C++ 11中聚合初始化有效的答案表明我们可以通过进行聚合初始化来消除拷贝/移动.

因此,我们可以在不需要执行任何移动或复制的情况下构建mypairs MAKE_PAIR.

我想概括MAKE_PAIRMAKE_TUPLE,即采取任何数量的参数.

要求是(如同MAKE_PAIR):

(1)推断类型.
(2)从临时建造(即施工到位)时,移动/复制被省略.

现有的库解决方案(例如Boost)会很好,但我更喜欢接受rvalue引用的东西.或者这里的代码也很棒,或者两者兼而有之.

如果它完全可能,我会喜欢它,如果它优化了空成员,同时仍然没有移动/复制构造函数调用,但我有一种感觉,这是太多了.

Pup*_*ppy 1

C++0x 标准库中已经有这样的功能 - a std::make_tuple. 即使你觉得无聊,你也可以自己做。

template<typename... T> std::tuple<T...> make_tuple(T...&& refs) {
    return std::tuple<T...> { std::forward<T>(refs)... };
}
Run Code Online (Sandbox Code Playgroud)