简体   繁体   中英

How to initialize a tuple of non-default-constructible not-copyable objects?

Given some classes with parameterized constructors, such as:

class A
{
public:
    A(bool b, int i) { /*...*/ }
private:
    A(const A&) {}
};
class B
{
public:
    B(char c, double d) { /* ... */ }
private:
    B(const B&) {}
};

How to properly initialize a tuple of such classes?

boost::tuple<A,B> tup( /* ??? */ );

Not using copy constructor of A or B, and, if possible, not using move-constructor either. C++03 solution preferred, if possible.

Can you just add a piecewise constructor for your types? If so, you can create a horrible macro that unpacks and delegates a tuple:

#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)...)                    \
    { }

And just add it to your types:

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)
};

And pass in tuples:

std::tuple<A, B> tup(
    std::forward_as_tuple(true, 42), 
    std::forward_as_tuple('x', 3.14));

Pre-C++11, I don't know that this is possible - you don't have delegating constructors at all. You'd have to either:

  1. Write your own tuple -like class that accepts tuples in its constructor
  2. Add tuple constructors to your types that explicitly initialize the same thing as the non-tuple versions did
  3. Have a tuple of types that are single-argument constructible, like boost::tuple<boost::scoped_ptr<A>, boost::scoped_ptr<B>>(new A(...), new B(...))

(1) is a lot of work, (2) is code duplication and error prone, and (3) involves now having to do allocation all of a sudden.

您可以使用以下内容:

tuple<A,B> tup(A(true, 42), B('*', 4.2));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM