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?
CodePudding user response:
std::bind does something completely different. Quoting cppreference
The function template
bindgenerates a forwarding call wrapper forf. Calling this wrapper is equivalent to invokingfwith some of its arguments bound toargs.
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...
