Search code examples
c++tuplesperfect-forwardingmember-initialization

How do I forward the values of tuple to a member initializer?


I need to forward the values of a tuple to a member initializer:

struct Struct {
  Member1 member1;
  Member2 member2;

  template<typename Tuple1, typename Tuple2>
    Struct( Tuple1&& tuple1, Tuple2&& tuple2 )
      : member1(tuple1...), member2(tuple2...)
    {}
};

The code above obviously isn't valid. How can I express it?

Member1 and Member2 have no default/copy/move constructor.

I know about std::apply, as suggested in How do I expand a tuple into variadic template function's arguments?. I also know about std::make_from_tuple. But I wouldn't know how to use any of these in a member initializer.

Any C++ standard is fine (preferably C++17, but C++20 would work as well).

To clarify, my real goal is to create a Struct, passing it two sets of variadic arguments to perfect-forward them to initialize member1 and member2. I thought that "grouping" the two sets into tuples could have been a good idea, since that's what std::map::emplace does. Other approaches would work as well (e.g. passing a special object between the two sets of variadic arguments).


Solution

  • std::make_from_tuple is indeed the right choice:

    #include <tuple>
    struct Member1 {
        Member1(int x,float y, char z){}
    
        Member1(const Member1& other)=delete;
        Member1(Member1&& other)=delete;
    };
    
    struct Member2 {
        Member2(int x,float y, char z){}
    
        Member2(const Member2& other)=delete;
        Member2(Member2&& other)=delete;
    };
    
    struct Struct {
      Member1 member1;
      Member2 member2;
    
      template<typename Tuple1, typename Tuple2>
        Struct(Tuple1&& tuple1, Tuple2&& tuple2)
          : member1(std::make_from_tuple<Member1>(std::forward<Tuple1>(tuple1))),
           member2(std::make_from_tuple<Member2>(std::forward<Tuple2>(tuple2)))
        {}
    };
    
    int main(){
        Struct c(std::tuple{1,1.1,'c'},std::tuple{2,2.2,'x'});
    }
    

    Godbolt demo.