【问题标题】:return type of a function template in C++ as second template parameterC++ 中函数模板的返回类型作为第二个模板参数
【发布时间】:2018-03-10 22:30:18
【问题描述】:

下面的模板如何实现?

std::result_of 不能那样工作。

我希望能够在外部通过其他方式更改 std::vector

我想将FV 保留在我的模板中

在 C++17 中首选

谢谢

template <typename F, typename V=vector<result_of<F>>, typename T, typename Ts ...>
auto call (F f, const T & t, const Ts & ... ts) {
  V v;  //  v is a container for values returned from f
  f(....);  // f is a funtion
  ....
  return v;
}

【问题讨论】:

  • 函数怎么调用?这很重要

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


【解决方案1】:

据我了解,您希望根据函数的返回类型提供默认模板参数,而无需函数参数类型。我不知道这样做的好方法,但这个 hack 似乎对你的情况有用

template <typename F, typename V=bool, typename T, typename... Ts>
auto call(F f, const T& t, const Ts&... ts) {
      using Container = typename std::conditional<std::is_same<bool,
      V>::value,
      std::vector<decltype(f(/*... whatever the args are*/))>,
      V>::type;

      Container c;
     // do stuff...
     return c;
}

【讨论】:

    【解决方案2】:

    不确定你想要什么...

    但我想是这样的

    template <template <typename...> class C = std::vector,
              typename F, typename T, typename ... Ts>
    auto call (F f, const T & t, const Ts & ... ts)
     {
       C<decltype(f(t))> v;
    
       (v.emplace_back(t), ..., v.emplace_back(ts));
    
       return v;
    }
    

    其中容器类型是第一个模板参数,默认为std::vector

    所以你可以打电话

    auto cv = call<std::vector>(foo, '0', '1', '2', '3');
    

    也可以

    auto cv = call(foo, '0', '1', '2', '3');
    

    但我看到的真正问题是:如何在容器中插入元素?

    我用过emplace_back(),想着std::vector;但是如果你想通过(例如)std::set,你找不到emplace_back(),而是emplace()。那你要不要也把insert方法作为模板参数传递?

    无论如何,以下是一个完整的工作示例

    #include <vector>
    #include <iostream>
    
    template <template <typename...> class C = std::vector,
              typename F, typename T, typename ... Ts>
    auto call (F f, const T & t, const Ts & ... ts)
     {
       C<decltype(f(t))> v;
    
       (v.emplace_back(t), ..., v.emplace_back(ts));
    
       return v;
    }
    
    int foo (char ch)
     { return ch; }
    
    int main()
     {
       auto cv = call(foo, '0', '1', '2', '3');
    
       for ( auto const & i : cv )
          std::cout << i << ' ';
    
       std::cout << std::endl;
     }
    

    【讨论】:

    • 谢谢。 @ max66,它可能会以某种方式帮助我,但我需要一些不依赖于 t 或 ts 值的东西......我想仅根据 o F 的值来计算 V 的值.....另外:假设我们有:.... char f (int, float).... V 将是.... vector 默认情况下,.....但我也希望能够用 std::string 替换 V 并将其作为模板参数传递
    • @EdgardLima - 我不清楚f() 收到哪些参数
    • @EdgardLima - 我的意思是......我能知道从f()返回的类型吗?
    • 会这样使用...... call([](auto x, auto y) { return x + y; }, {1,2,3}, {10, 20,30}); .......我的最终结果将是 {11,22,33} .... "f" 的返回可能是任何类型,....它将非常通用....在这个情况下,f 返回 int,所以 V 将是 vector .... 但我可以选择使用 ..... call(int,int), deque)[](auto x , 自动 y) { 返回 x + y; }, {1,2,3}, {10,20,30});
    【解决方案3】:

    我终于明白了

    template <typename Rt = void, typename F, typename T, typename... Ts>
          auto mapf(F f, const T & t, const Ts & ... ts) {
              auto m = minsize(t, ts...);
              using Vt = decltype(std::forward<F>(f)(*begin(t), *begin(ts)...));
              using V = typename std::conditional<is_same<Rt,void>::value, vector<Vt>, Rt>::type;
              V r;                                                                                                                                                                                                                                                               
              r.resize(m);
              for(auto i = 0u; i < m; i++) {
                  auto tuples =  make_tuple(*next(begin(t),i), *next(begin(ts),i)...);
                 auto v = apply<tuple<typename T::value_type, typename Ts::value_type ...>>(tuples, forward<F>(f));
                  *next(begin(r),i) = move(v);
              }    
              return r;
          }
    

    【讨论】:

    • 为了我自己的启迪,这和我给出的答案有什么不同?
    猜你喜欢
    • 1970-01-01
    • 2018-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-10
    • 1970-01-01
    相关资源
    最近更新 更多