【问题标题】:C++17 parameter pack expansion with function parameter evaluation带有函数参数评估的 C++17 参数包扩展
【发布时间】:2020-08-06 21:30:04
【问题描述】:

我正在使用可变参数模板和折叠表达式,特别是进行类型转换以放入函数参数中。我的理解是这样做:

template<T, typename ... Args>
void convertAndEvaluate(const vector<T>& convertibles)
{
    size_t i = 0;
    evaluate(some_function<Args>(convertibles[i++])...);
}

由于未指定函数输入的评估顺序,因此无法正常工作。折叠表达式可以给出正确的求值顺序,但是它们的结果用括号括起来,不能用作函数输入。我可以通过另一个模板函数使用 index_sequences 实现相同的结果,但我想知道 C++17 是否有更简洁的方法,例如使用 constexpr 和包扩展。

玩具示例:

#include <iostream>
#include <vector>
#include <utility>

using namespace std;

template<typename ... Args>
class Foo {
public:
    Foo() {}
    
    void just_print(const std::vector<int>& convertible)
    {
        size_t i = 0;
        ((cout << static_cast<Args>(convertible[i++]) << " "), ...);
        cout << endl;
    }

    template<typename T,T... ints>
    void expandEvaluate(const std::vector<int>& values, std::integer_sequence<T, ints...> int_seq)
    {
        eval(static_cast<Args>(values[ints])...);
    }
  
    void convert(const std::vector<int>& convertible)
    {
        expandEvaluate(convertible, std::make_index_sequence<sizeof...(Args)>());
    }
    
    void convert_wrong(const std::vector<int>& convertible)
    {
        size_t i = 0;
        eval(static_cast<Args>(convertible[i++])...);
    }
    
    void eval(const Args&... values)
    {
        ((cout << values << " "), ...);
        cout << endl;
    }
    
};


int main()
{
    
    Foo<double, int, float, int, double> bar;
    bar.eval(3, 4, 5, 6, 7);
    bar.just_print({3, 4, 5, 6, 7});
    bar.convert_wrong({3, 4, 5, 6, 7});
    bar.convert({3, 4, 5, 6, 7});
    return 0;
}

输出:

3 4 5 6 7                                                                                                                                                 
3 4 5 6 7                                                                                                                                                 
7 6 5 4 3                                                                                                                                                 
3 4 5 6 7

编辑: 回想起来,我的整数扩展解决方案需要同时扩展两个参数包,这是在标准中定义的吗?

【问题讨论】:

    标签: c++17 variadic-templates variadic-functions template-meta-programming


    【解决方案1】:

    我认为您的解决方案(使用 std::make_index_sequence/std::index_sequence 以正确顺序获取索引)是一个很好的解决方案(并且也适用于 C++14)。

    从 C++17 开始你也可以使用std::tuple/std::apply()

    void convert2 (std::vector<int> const & cv)
     {
       std::size_t  i{};
    
       std::tuple  t{ static_cast<Args>(cv[i++])... };
       std::apply([=](auto ... args){ eval(args...); }, t);
     }
    

    但这几乎是您的std::make_index_sequence/std::index_sequence 解决方案,由std::apply() 包装。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-12-09
      • 1970-01-01
      • 1970-01-01
      • 2013-08-31
      • 1970-01-01
      • 2015-12-01
      相关资源
      最近更新 更多