代码之家  ›  专栏  ›  技术社区  ›  GaryO

C++中的多级函数模板

  •  0
  • GaryO  · 技术社区  · 7 年前

    我尝试用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 使用实际的类型名 Proc_v1_to_v1 ,它起作用。但我不明白为什么编译器不能推断出类型。我做错什么了?

    2 回复  |  直到 7 年前
        1
  •  1
  •   r3mus n0x    7 年前

    模板参数推导在传递 函数参数 其类型由 模板参数 :

    template<typename Processor>
    void dispatch(Processor processor, const std::vector<float> src, std::vector<float> dst, int mode);
    
    dispatch(process_vec1<add1_op>, src, dst, mode);
    

    但是,在您的情况下,您将向函数传递一个指针 process_vec1<add1_op> (这是一个 价值 )作为模板参数的参数 Processor 这是一个 类型 . 这就是错误的原因:对于类型参数,值是错误的参数。

    如果确实要使用模板参数指定函数,可以:

    • 制作 处理器 非类型模板参数 Proc_v1_to_v1
    • 或制造 process_vec1 像雅克在回答中建议的那样,变成了一个函数。
        2
  •  1
  •   Yakk - Adam Nevraumont    7 年前

    使用无状态函数对象。

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