【问题标题】:std::tuple unpack over multiple argumentsstd::tuple 在多个参数上解包
【发布时间】:2021-04-09 14:11:57
【问题描述】:

我有一个函数将 (argument type, data ptr) 对作为可变参数列表(C 函数)。我想将元组解压缩到该函数中,如下所示:
foo(TypeIndex<std::tuple_element_t<I, Tuple>>(), &std::get<I>(tuple)); 因此我编写了以下函数:

template<typename Tuple, size_t ...I>
void doUnpack(Tuple const& tp, std::index_sequence<I...>)
{
    foo((type<std::tuple_element_t<I, Tuple>>(), std::get<I>(tp))...);
}

唯一的问题是逗号运算符忽略了左侧的所有内容,使用右侧。想象一下type&lt;&gt; 函数现在返回 0,所以上面的计算(使用输入元组{1,2,3,4,5})为foo(1,2,3,4,5) 而不是foo(0,1, 0,2, 0,3, 0,4, 0,5)

有没有办法做到这一点?


要重现的代码:

template<typename Tp>
int type() { return 0; }

template<typename ...Args>
void fun(Args&& ...args)
{
    (std::cout << ... << args) << std::endl;
}

template<typename Tuple, size_t ...I>
void doUnpack(Tuple const& tp, std::index_sequence<I...>)
{
    fun((type<std::tuple_element_t<I, Tuple>>(), std::get<I>(tp))...);
}

int main()
{
    doUnpack(std::tuple{1,2,3,4,5}, std::make_index_sequence<5>{});
    return 0;
}

【问题讨论】:

  • 这里的问题是这里的,被解析为一个逗号操作符,它几乎忽略了它左边表达式的结果,而使用右边表达式的;而不是 , 作为函数参数分隔符。您是否考虑过将类型/值的std::tuple 传递给您的foo,而不是将它们作为离散参数?这将巧妙地回避这个问题。
  • @SamVarshavchik 我认为这似乎是目前唯一的解决方案。谢谢!

标签: c++


【解决方案1】:

以下是你想要的:

#include <tuple>
#include <iostream>

template<typename Tp>
int type() {
    return 0;
}

template<typename Tuple, size_t... I>
auto doUnpack(Tuple const &tp, std::index_sequence<I...>) {
    auto fun = [](auto &&...args) { (std::cout << ... << args) << std::endl; };
    std::apply(fun, std::tuple_cat(std::pair{type<std::tuple_element_t<I, Tuple>>(), std::get<I>(tp)}...));
}

int main() {
    doUnpack(std::tuple{1, 2, 3, 4, 5}, std::make_index_sequence<5>{});
    return 0;
}

我们使用了两个不错的 STL 函数。 std::tuple_cat 采用一堆元组(这里是元组的类型和值对)并将它们连接到一个大元组。所以你从(type0, val0), (type1, val1)... 转到(type0, val0, type1, val1, ...)。这解决了逗号运算符的问题。之后,我们将函数应用于std::apply。请注意,我使用 lambda 是因为 std::apply 需要(基本上)具有类型的可调用对象,而函数模板不符合条件(而 lambda (基本上)是具有模板化 operator() 的结构,适用于此。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-01-06
    • 1970-01-01
    • 2012-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-20
    相关资源
    最近更新 更多