C ++ 11转发模板模板参数不起作用

时间:2017-08-16 12:40:26

标签: c++11 templates perfect-forwarding

我使用模板模板参数如下:

    /* [1]: Definition containing a template template parameter */
          template <typename T, template<class> class Kernel>
          void ForEach(Kernel<T> kernel, T * pSrc, int elementCount) {
               //....
          }

    /* [2]: Definition of a helper struct */
          template <typename T> struct KernelStd {  
               //...
          };

    /* [3]: Use the previous definitions */
          float arr1[5] = {1,2,3,4,5};

          //The following two calls to ForEach do successfully compile
          ForEach(KernelStd<float>(), arr1, 5); //USE1
          ForEach<float>(KernelStd<float>(), arr1, 5); //USE2

    /* [4]: Definition of a helper function */      
          template <typename F, typename ...Args>
          void forwarder(F func1, Args && ...args) {
                //...
                func1(std::forward<Args>(args)...);
          }
          //But the following callS do not compile.
          forwarder(ForEach, KernelStd<float>(), arr1, 5); //USE3
          forwarder(ForEach<float>, KernelStd<float>(), arr1, 5); //USE4 

我正在使用VS2013更新5,我收到以下错误:

         error C2783: 'void ForEach(Kernel<T>,T *,int)' : could not deduce 
         template argument for 'Kernel'

任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

forwarder是一个函数,因此它的第一个参数必须是F类型的实体(对象或函数)。

ForEach既不是函数也不是对象,它是模板。因此,您无法将ForEach传递给forwarder

ForEach<float>没有传递足够的模板参数来完全标识从ForEach模板实例化的函数。由于模板参数推断,在调用函数模板时可以使用它。但是在forwarder的上下文中,类型F应该从第一个参数推断出来,所以你有一点鸡蛋和鸡蛋的问题。

如果要使用forwarder,则必须为其提供实际功能,而不是模板。所以你必须这样做:

forwarder(ForEach<float, KernelStd>, KernelStd<float>(), arr1, 5);

ForEach<float, KernelStd>包含所有模板参数,因此它指定函数(从模板实例化)。