Partial Constructor arguments from tuple

In C++17 there's std::make_from_tuple; However that only applies to situations where the number of the elements stored in the tuple matches with that of the constructor.

I was able to concatenate two tuples and use std::make_from_tuple.

#include <iostream>
#include <utility>
#include <tuple>

class ConstructMe{
public:
  ConstructMe(int a_, int b_, int c_)
  : a(a_), b(b_), c(c_) { }

private:
  int a;
  int b, c;
};

int main(){
  int a = 1;
  std::tuple<int, int> part = std::make_tuple(2,3);
  ConstructMe please = std::make_from_tuple<ConstructMe>(
    std::tuple_cat(std::make_tuple(a), part)
  );
  return 0;
}

And after some research ( this question I was able to make it work with references as well with std::tie as well.

#include <iostream>
#include <utility>
#include <tuple>

class ConstructMe{
public:
  ConstructMe(int& a_, int b_, int c_)
  : a(a_), b(b_), c(c_) { }

private:
  int& a;
  int b, c;
};

int main(){
  int a = 1;
  std::tuple<int, int> part = std::make_tuple(2,3);
  ConstructMe please = std::make_from_tuple<ConstructMe>(
    std::tuple_cat(std::tie(a), part)
  );
  return 0;
}

Is there a simpler way to do this ( e.g. with std::bind) which doesn't require c++17?


std::bind does something completely different. Quoting cppreference

The function template bind generates a forwarding call wrapper for f. Calling this wrapper is equivalent to invoking f with some of its arguments bound to args.

You can just use the cpp reference link to build your own implementation of the standardized function, e.g. in C++14

#include <iostream>
#include <utility>
#include <tuple>

namespace detail {
template <class T, class Tuple, std::size_t... I>
constexpr T make_from_tuple_impl( Tuple&& t, std::index_sequence<I...> )
{
    static_assert(std::is_constructible<T,
        decltype(std::get<I>(std::declval<Tuple>()))...>::value);
    return T(std::get<I>(std::forward<Tuple>(t))...);
}
} // namespace detail
 
template <class T, class Tuple>
constexpr T make_from_tuple( Tuple&& t )
{
    return detail::make_from_tuple_impl<T>(std::forward<Tuple>(t),
        std::make_index_sequence<std::tuple_size<std::remove_reference_t<Tuple>>::value>{});
}

class ConstructMe{
public:
  ConstructMe(int& a_, int b_, int c_)
  : a(a_), b(b_), c(c_) { }

private:
  int& a;
  int b, c;
};

int main(){
  int a = 1;
  std::tuple<int, int> part = std::make_tuple(2,3);
  ConstructMe please = make_from_tuple<ConstructMe>(
    std::tuple_cat(std::tie(a), part)
  );
}

If you want to go back more language versions, you have to do more by hand. It will be harder and harder, especially if you want to go before C++11...