Даны некоторые классы с параметризованными конструкторами, такими как:
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, и, если возможно, также не использовать move-constructor. Решение 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));