考虑以下
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);
}
回答 C++11中什么时候聚合初始化是有效的 说我们可以通过进行聚合初始化来省略复制/移动。
因此,我们可以使用MAKE_PAIR
构造mypair
而无需执行任何移动或复制操作。
我想将MAKE_PAIR
泛化为MAKE_TUPLE
,即接受任意数量的参数。
要求如下(与MAKE_PAIR
相同):
(1) 类型被推断。
(2) 当从临时对象构造时省略移动/复制(即在原地进行构造)。
现有的库解决方案(例如Boost)也可以,尽管我更喜欢接受右值引用的东西。或者只是在这里编写的代码也很好,或者两者混合使用。
如果可能的话,我希望它能优化出空成员,同时仍然省略移动/复制构造函数调用,但我感觉这要求太高了。
std::make_tuple
使用最佳的构造函数,这真的不应该有任何影响。通过元组提供的花哨结构来支持它们的成本就是它们不是聚合体。我不确定为什么你会如此担心这个额外的步骤,几乎肯定在你的代码中会有更大的性能瓶颈。 - Kerrek SB