我正在尝试创建一个不可复制对象的元组。当我有了复制构造函数时,我就可以构造元组了。当它们被删除时,编译失败。
#include <tuple>
#include <iostream>
#include <utility>
struct A {
int& x;
int& y;
A(int& a, int& b) : x(a), y(b) {}
A(const A&) = delete;
A& operator=(const A&) = delete;
};
class B {
public:
B(int& w, int& x, int& y, int& z)
: a_b_{ A(w,x),A(y,z)} {}
private:
std::tuple<A, A> a_b_;
};
int main() {
int w =1, x=2, y=3, z=4;
B b{w,x,y,z};
return 0;
}
我能够通过添加一个元组构造函数来实现它。
struct A {
int& x;
int& y;
A(int& a, int& b) : x(a), y(b) {}
A(const A&) = delete;
A& operator=(const A&) = delete;
template<typename ...Args>
A(const std::tuple<Args...> &args)
: A(args, std::index_sequence_for<Args...>{}) {}
template<typename ...Args, std::size_t ...Is>
A(const std::tuple<Args...> &args, std::index_sequence<Is...>)
: A(std::get<Is>(args)...) {}
};
class B {
public:
B(int& w, int& x, int& y, int& z)
: a_b_{ std::forward_as_tuple(w,x), std::forward_as_tuple(y,z)} {}
private:
std::tuple<A, A> a_b_;
};
这并不理想,因为它需要将此构造函数添加到我的所有类中。有没有不需要改变元组中对象的解决方案?谢谢!
C++17 中有一种方法。在 C++11/14 中不起作用,因为在 C++17 中 RVO 是强制性的。
它需要一个用于构造
C
的中间类A
。在 C++17 之前的版本中,您必须向 A
. 添加一个额外的构造函数
#include <tuple>
#include <iostream>
#include <utility>
struct A {
int& x;
int& y;
A(int& a, int& b) : x(a), y(b) {}
A(const A&) = delete;
A& operator=(const A&) = delete;
};
struct C {
int* x;
int* y;
C(int& a, int& b) : x(&a), y(&b) {};
operator A () const
{
return A(*x,*y);
}
};
class B {
public:
B(int& w, int& x, int& y, int& z)
: a_b_{ C{w,x}, C{y,z}} {}
private:
std::tuple<A, A> a_b_;
};
int main() {
int w =1, x=2, y=3, z=4;
B b{w,x,y,z};
return 0;
}
如果您要使用
std::pair
而不是std::tuple
,您也可以通过std::piecewise_construct
来实现它。看,
#include <tuple>
#include <iostream>
#include <utility>
struct A {
int& x;
int& y;
A(int& a, int& b) : x(a), y(b) {}
A(const A&) = delete;
A& operator=(const A&) = delete;
};
class B {
private:
std::pair<A, A> a_b_;
public:
B(int& w, int& x, int& y, int& z)
: a_b_{std::piecewise_construct, std::forward_as_tuple(w,x), std::forward_as_tuple(y,z)} {}
};
int main() {
int w =1, x=2, y=3, z=4;
B b{w,x,y,z};
return 0;
}
如果可以使用“对”而不是“元组”作为类
B
的私有数据成员,那么我们可以如下使用类标签piecewise_construct_t
,而无需在类中进行任何更改A
:
struct A {
int& x;
int& y;
A(int& a, int& b) : x(a), y(b) {}
A(const A&) = delete;
A& operator=(const A&) = delete;
};
class B {
public:
B(int& w, int& x, int& y, int& z)
: a_b_{std::piecewise_construct,
std::forward_as_tuple(w,x),
std::forward_as_tuple(y,z)} {}
private:
std::pair<A, A> a_b_;
};