首页 > 解决方案 > C++ 中的多级函数模板

问题描述

我正在尝试使用 C++14 以通用方式处理向量。我有以下代码,从我的真实示例中简化(我知道这可以用 std 的东西来完成,我的真实示例是多线程的,而且要复杂得多):

#include <vector>

// there will be lots of these
struct add1_op {
  static inline void doit(float x0, float& dst) {
    dst = x0 + 1;
  }
};

// there will be multiples of these with different args
template<class Op>
void process_vec1(const std::vector<float> src, std::vector<float> dst)
{
  for (size_t i = 0; i < src.size(); i++) {
    Op::doit(src[i], dst[i]);
  }
}

using Proc_v1_to_v1 = void (*)(const std::vector<float>, std::vector<float>);

template<typename Processor> // NOTE: works with <Proc_v1_to_v1 Processor>
void dispatch(const std::vector<float> src, std::vector<float> dst, int mode)
{
  if (mode == 0)
    Processor(src, dst);
  // ... other modes ...
}

void add1_vec(const std::vector<float> src, std::vector<float> dst, int mode)
{
  dispatch<process_vec1<add1_op> >(src, dst, mode);
}

这在 MacOS 上不能用 clang 编译:gets error: no matching function for call to 'dispatch',说foo.cxx:28:6: note: candidate template ignored: invalid explicitly-specified argument for template parameter 'Processor'

如果我typename Processor用实际的 typename替换Proc_v1_to_v1,它可以工作。但我不明白为什么编译器不应该能够推断出类型。我究竟做错了什么?

标签: c++templates

解决方案


使用无状态函数对象。

struct add1_op {
  void operator()(float x0, float& dst) const {
    dst = x0 + 1;
  }
};

template<class Op>
struct process_vec1{
  void operator()(const std::vector<float> src, std::vector<float> dst) const {
    for (size_t i = 0; i < src.size(); i++) {
      Op{}(src[i], dst[i]);
    }
  }
};

推荐阅读