给定一些具有参数化构造函数的类,例如:
class A
{
public:
A(bool b, int i) { /*...*/ }
private:
A(const A&) {}
};
class B
{
public:
B(char c, double d) { /* ... */ }
private:
B(const B&) {}
};
如何正确初始化此类的元组?
boost::tuple<A,B> tup( /* ??? */ );
不使用A或B的复制构造函数,如果可能,也不使用移动构造函数。如果可能的话,优选C++03溶液。
你能为你的类型添加一个分段构造函数吗?如果是这样的话,您可以创建一个可怕的宏,它可以打开包装并委托一个元组:
#define CONSTRUCT_FROM_TUPLE(CLS)
template <class... Ts>
CLS(std::tuple<Ts...> const& tup)
: CLS(tup, std::index_sequence_for<Ts...>{})
{ }
template <class Tuple, size_t... Is>
CLS(Tuple const& tup, std::index_sequence<Is...> )
: CLS(std::get<Is>(tup)...)
{ }
只需将其添加到您的类型中即可:
struct A {
A(bool, int ) { }
A(const A& ) = delete;
CONSTRUCT_FROM_TUPLE(A)
};
struct B {
B(char, double ) { }
B(const B& ) = delete;
CONSTRUCT_FROM_TUPLE(B)
};
并传入元组:
std::tuple<A, B> tup(
std::forward_as_tuple(true, 42),
std::forward_as_tuple('x', 3.14));
在C++11之前,我不知道这是可能的——你根本没有委派构造函数。你必须:
- 编写自己的类
tuple
,它在构造函数中接受元组 - 将元组构造函数添加到类型中,这些类型显式初始化与非元组版本相同的内容
- 具有可单参数构造的类型元组,如
boost::tuple<boost::scoped_ptr<A>, boost::scoped_ptr<B>>(new A(...), new B(...))
(1) 是一项艰巨的工作,(2)是代码重复和容易出错的问题,(3)涉及到现在必须突然进行分配。
您可以使用以下内容:
tuple<A,B> tup(A(true, 42), B('*', 4.2));