【问题标题】:Call variadic templated function with arguments from a std::vector使用来自 std::vector 的参数调用可变参数模板函数
【发布时间】:2021-07-22 06:12:03
【问题描述】:

我需要将 std::vector 的元素转换为基于模板参数的类型,并使用这些参数调用函数。在伪代码中:

template <typename T...>
void foo(std::vector<std::string> v) {
    if (v.size() != sizeof...(T))
        throw std::runtime_error("Bad");

    bar(convert<T0>(v[0]), convert<T1>(v[1]), ..., convert<Tn>(v[n]));
}

我的问题是如何从参数包中获取元素索引,我认为使用折叠表达式会有某种技巧,但我想不通。

【问题讨论】:

  • 根据经验,类型(这里是可变参数模板参数大小)不能依赖于运行时值(这里是向量的大小)。这只有在您知道最大向量大小的情况下才有可能,通过使用模板预先生成样板来调用最多 N 个参数的函数。
  • 我假设向量大小等于参数包大小,并且在运行时检查它,在魔术发生之前。这对我来说似乎很明显,所以我没有提到它。我的错 :)。我已经编辑了代码以包含检查。

标签: c++ c++17 variadic-templates


【解决方案1】:

如果你知道一个向量中的元素个数等于参数包大小,你可以通过增加一层间接来解决这个问题:

template<typename... T, std::size_t... is>
void foo_impl(const std::vector<std::string>& v, std::index_sequence<is...>) {
    bar(convert<T>(v[is])...);
}


template<typename... T>
void foo(const std::vector<std::string>& v) {
    assert(v.size() == sizeof...(T));
    foo_impl<T...>(v, std::index_sequence_for<T...>{});
}

这里的想法是同时扩展两个包,Ts...is...,它们的大小相同。


C++20 解决方案:

template<typename... T>
void foo(const std::vector<std::string>& v) {
    assert(v.size() == sizeof...(T));

    [&v]<std::size_t... is>(std::index_sequence<is...>) {
        bar(convert<T>(v[is])...);
    }(std::index_sequence_for<T...>{});
}

【讨论】:

    【解决方案2】:

    您可以通过使用std::integer_sequence 访问向量的元素来解决此问题。

    namespace detail
    {
    template <typename...T, size_t...I>
    void foo(std::vector<std::string>& v, std::index_sequence<I...>) {
        bar(convert<T>(v[I])...);
    }
    }
    
    template <typename...T>
    void foo(std::vector<std::string>& v) {
        if (v.size() != sizeof...(T))
            throw std::runtime_error("Bad");
        detail::foo<T...>(v, std::index_sequence_for<T...>{});
    }
    

    在 Godbolt 上:Link

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-10-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-09
      • 1970-01-01
      • 1970-01-01
      • 2019-01-23
      • 2019-01-18
      相关资源
      最近更新 更多