如何使此模板方法更优雅? (或:所需的显式模板参数较少) [英] How can I make this template method more elegant? (or: less explicit template parameters required)

查看:65
本文介绍了如何使此模板方法更优雅? (或:所需的显式模板参数较少)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的目标是拥有一个模板函数,该模板函数将输入对象和函数对象的std :: vector作为输入。然后,该模板函数将使用函数对象和线程池将输入向量转换为转换后对象的std :: vector。

My goal was to have a template function that would take as an input a std::vector of input objects and a function object. This template function would then turn the input vector into a std::vector of converted objects by using the function object and a threadpool.

下面包含示例代码。

我真的希望能够使用比首先创建一个本地函数对象然后传递所有模板参数短的语法。

I would really like to be able to use a shorter syntax than first creating a local function object, and then passing on all the template parameters.

使用gcc进行编译:g ++ -std = C ++ 0x bla.cpp

Compile with gcc: g++ -std=C++0x bla.cpp

#include <vector>
#include <functional> 
#include <iostream>

// SYNTAX:
// vector<ResultType> transformed = multiTransform(const vector<InputType>, Transform t)
// where Transform t takes a single InputType as an argument
// ConvertedType has to be default constructible
template <class ConvertedType, class InputType, class Transform>
std::vector<ConvertedType> multiTransform(const std::vector<InputType>& inputs, Transform t) {
  std::vector<ConvertedType> results(inputs.size());
  {
    // boost::threadpool::pool pool(boost::thread::hardware_concurrency());
    for(auto it = inputs.begin(); it != inputs.end(); ++it){
      auto inputDereferenced = *it;
      auto functor = [&, it, inputDereferenced](){
        auto result = t(inputDereferenced);
        results[it - inputs.begin()] = std::move(result);
      };
      // pool.schedule(functor);
      functor();
    }
  }
  return results;
}

int main() {
  std::vector<int> input = {1,2,3};
  // auto output = multiTransform(input, [](int a){return float(a);}); // does not compile
  auto lambda = [](int a){return a/2.0;};
  auto output = multiTransform<float, int, decltype(lambda)>(input, lambda);

  for(auto it : output){
    std::cout << it << std::endl;
  }
}


推荐答案

此使用g ++ 4.6.3为我工作:

This works for me with g++ 4.6.3:

auto output = multiTransform<float>(input, [](int a){return a/2.0;});

您还可以使模板声明更加复杂:

You can also make your template declaration a bit more sophisticated:

template <class InputType, class Transform>
auto
multiTransform(const std::vector<InputType>& inputs, Transform t)
  -> std::vector<decltype(t(*inputs.begin())) >
{
  typedef decltype(t(*inputs.begin())) ConvertedType;
  std::vector<ConvertedType> results(inputs.size());
  {
    // boost::threadpool::pool pool(boost::thread::hardware_concurrency());
    for(auto it = inputs.begin(); it != inputs.end(); ++it){
      auto inputDereferenced = *it;
      auto functor = [&, it, inputDereferenced](){
        auto result = t(inputDereferenced);
        results[it - inputs.begin()] = std::move(result);
      };
      // pool.schedule(functor);
      functor();
    }
  }
  return results;
}

然后您就可以使用

auto output = multiTransform(input, [](int a){return a/2.0;});

这篇关于如何使此模板方法更优雅? (或:所需的显式模板参数较少)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆