c++ - 我怎样才能使这个模板方法更优雅? (或 : less explicit template parameters required)

标签 c++ templates lambda c++11

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

示例代码如下。

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

用 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:

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

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

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;});

关于c++ - 我怎样才能使这个模板方法更优雅? (或 : less explicit template parameters required),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10350795/

相关文章:

c++ - Typedef、模板和 const 关键字

c++ - 具有类型特征的通用 lambda

c# - 如何在 LINQ lambda 中执行多个表之间的连接

c++ - std::find_if 、 std::binary_function 用于按值搜索 std::map

c++ - 使用 std::shared_ptr/weak_ptr 简化观察者模式

c++ - 使用自定义分配器计算内存使用情况

c++ - 将 float 四舍五入到小数点后一位,然后转换为字符串

c++ - 根据单独的模板化成员改变类的模板化成员函数的返回类型

java - 如何使用 Java 8 对 List<int[]> 中的值求和

c++ - QTabWidget 隐藏和显示标签