来自元组的部分构造函数参数
Partial Constructor arguments from tuple
在 C++17 中有 std::make_from_tuple
;但是,这仅适用于存储在元组中的元素数量与构造函数中的元素数量匹配的情况。
我能够连接两个元组并使用 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;
}
经过一些研究( I was able to make it work with references as well with std::tie
。
#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;
}
是否有不需要 c++17 的更简单的方法(例如 std::bind
)?
std::bind
做了完全不同的事情。引用 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
.
您可以只使用 cpp 参考 link 来构建您自己的标准化函数实现,例如在 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)
);
}
如果你想返回更多的语言版本,你必须做更多的手工。它会越来越难,特别是如果你想在 C++11 之前...
在 C++17 中有 std::make_from_tuple
;但是,这仅适用于存储在元组中的元素数量与构造函数中的元素数量匹配的情况。
我能够连接两个元组并使用 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;
}
经过一些研究(std::tie
。
#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;
}
是否有不需要 c++17 的更简单的方法(例如 std::bind
)?
std::bind
做了完全不同的事情。引用 cppreference
The function template
bind
generates a forwarding call wrapper forf
. Calling this wrapper is equivalent to invokingf
with some of its arguments bound toargs
.
您可以只使用 cpp 参考 link 来构建您自己的标准化函数实现,例如在 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)
);
}
如果你想返回更多的语言版本,你必须做更多的手工。它会越来越难,特别是如果你想在 C++11 之前...