我有一个 A
类的对象,可以用不同的类型调用它,并在每次调用时返回改变的 self 。出于这个问题的目的 A
会做
struct A {
A call(const int&) {
}
A call(const string& s) {
}
////
} a;
所以我有一个未知类型的元组:
std::tuple<Types...> t;
我想用每个元组元素调用
a
,所以我想得到类似的东西:b = a;
b = b.call(get<0>(t));
b = b.call(get<1>(t));
b = b.call(get<2>(t));
//...
或者
b = a.call(get<0>(t)).call(get<1>(t)).call(get<2>(t)...)
顺序并不重要(我的意思是如果调用顺序颠倒甚至洗牌也没关系)。
我确实理解递归是可能的,但它很丑陋。不递归可以实现吗?
最佳答案
您可以使用 std::index_sequence<Is...>
,例如:
namespace detail
{
template <std::size_t...Is, typename T>
void a_call(A& a, std::index_sequence<Is...>, const T& t)
{
int dummy[] = {0, ((a = a.call(std::get<Is>(t))), void(), 0)...};
static_cast<void>(dummy); // Avoid warning for unused variable.
}
}
template <typename ... Ts>
void a_call(A& a, const std::tuple<Ts...>& t)
{
detail::a_call(a, std::index_sequence_for<Ts...>{}, t);
}
在 C++17 中,折叠表达式允许:
template <std::size_t...Is, typename T>
void a_call(A& a, std::index_sequence<Is...>, const T& t)
{
(static_cast<void>(a = a.call(std::get<Is>(t))), ...);
}
甚至,使用
std::apply
:template <typename ... Ts>
void a_call(A& a, const std::tuple<Ts...>& t)
{
std::apply([&](const auto&... args){ (static_cast<void>(a = a.call(args)), ...); }, t);
}
关于c++ - 为一个对象上的每个元组元素调用函数而无需递归,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/32460653/