0

Is it possible to initialize a member of a class (or call superclass constructor) by using the arguments contained in a tuple? Please note that I am aware of std::make_from_tuple() and std::apply() but they cannot be used in this scenario.

Consider sometype is non copyable, non default constructible, non movable, non assignable, non anything else. The only way to instantiate it is by using using the arguments that are provided as a std::tuple. Can this be done?

My attempt fails as appereantly "expansion pattern contains no argument pack" though the index_sequence generate should be one.

class node {
    public:
    sometype value;
    template <typename... Args>
    explicit node(const std::tuple<Args...>& args_tuple) :
            value(
                std::get<
                    std::index_sequence_for<Args...>{}
                >(args_tuple)...
            ) {
    }
};
barsan-md
  • 873
  • 8
  • 25
  • 4
    `std::make_from_tuple()` should work thanks to guaranteed copy elision. Did you try it? – Brian Bi Oct 16 '18 at 20:00
  • Do you have to take a tuple? If not you can use `explicit node(Args...&& args) : value(std::forward(args)...) {}` – NathanOliver Oct 16 '18 at 20:03
  • Also related/dupe: https://stackoverflow.com/questions/7858817/unpacking-a-tuple-to-call-a-matching-function-pointer – NathanOliver Oct 16 '18 at 20:07
  • `But they cannot be used in this scenario` - why? – SergeyA Oct 16 '18 at 20:12
  • "but they cannot be used in this scenario." Why not? – Barry Oct 16 '18 at 20:12
  • Because the value that is being constructed is non copiable, non assignable – barsan-md Oct 17 '18 at 07:58
  • @Brian I tried now, std::make_from_tuple seems to be working, though this is counter intuitive. If the semantics of the language is appearenatly being broken by allowing you to "copy" withouth having access to a copy constructor, then what is the point of all emplace methods that containers have? – barsan-md Oct 17 '18 at 08:13
  • As a side note, I don't understand the reason for a -1. – barsan-md Oct 17 '18 at 08:14

1 Answers1

3

If you insist on not using std::make_from_tuple(), you need another level of indirection:

public:
    explicit node(const std::tuple<Args...>& args_tuple) :
        node(args_tuple, std::make_index_sequence<sizeof...(Args)>{})
    { }

private:
    template<class Tuple, std::size_t... is>
    node(const Tuple& args_tuple, std::index_sequence<is...>) :
        value(std::get<is>(args_tuple)...)
    { }
Evg
  • 23,109
  • 5
  • 38
  • 74