将非模板函数指针传递给模板方法

时间:2013-11-19 21:43:57

标签: c++ templates pointers const

我搜索了Google和stackoverflow,无法找到解决此问题的内容:

  1. 我有一个带有函数指针的方法的模板。
  2. 函数指针本身不是模板,它是一个普通的函数指针。
  3. 但是,函数指针在其参数
  4. 中使用了模板args

    文件名:otherclasses.h

    // This class is used as the template parameter
    class B
    {
      public:
        B() {}
        ~B() {}
    
        int getVal() const { return val; }
        void setVal(int v) { val = v; }
      private:
        int val;
    };
    
    // This is just a static function
    class A
    {
      public:
        static bool someStaticFunction(const B* left, const B* right);
    };
    
    inline
    bool
    A::someStaticFunction(
        const B* left, 
        const B* right)
    {
      return left->getVal() < right->getVal();
    }
    

    文件名:templateheader.h

    #include "otherclasses.h"
    template<typename T>
    class theTemplate
    {
      public:
        void insert(T val1, T val2)
          {
            stuff[0] = val1;
            stuff[1] = val2;
          }
        bool usesSomeStaticFunction(bool (*funcp)(const T, const T))
          { 
            // will return true
            return funcp(stuff[0],stuff[1]);
          }
      private:
        T stuff[2];
    };
    

    文件名:main.cpp

    #include "otherclasses.h"
    #include "templateheader.h"
    #include <stdio.h>
    
    int main() 
    {
      theTemplate<B*> foo;
      printf("%d\n", foo.usesSomeStaticFunction(A::someStaticFunction));
      return 0;
    }
    

    Visual Studio中的错误:

    error C2664: 'theTemplate<T>::usesSomeStaticFunction' : cannot convert 
    parameter 1 from 'bool (__cdecl *)(const B *,const B *)' to 
                     'bool (__cdecl *)(const T,const T)'
      with
      [
        T=B *
      ]
    None of the functions with this name in scope match the target type
    

    解决此问题的两种方法:

    1. 使用const void*代替const T*
    2. 从函数指针的参数和使用它的任何内容中删除const
    3. 感谢您的帮助

      更新

      原来有一个更好的解决方案 - 只需将const移动到静态函数中B*的右侧:

      文件名:otherclasses.h已编辑

      // This class is used as the template parameter
      // This is unchanged.
      class B
      {
        public:
          B() {}
          ~B() {}
      
          int getVal() const { return val; }
          void setVal(int v) { val = v; }
        private:
          int val;
      };
      
      // This is just a static function
      // This is changed
      class A
      {
        public:
          // The "const" is moved to the right side of B*
          static bool someStaticFunction(B* const left, B* const right);
      };
      
      // This is changed
      inline
      bool
      A::someStaticFunction(
          // The function definition must match the function prototype...
          B* const left, 
          B* const right)
      {
        return left->getVal() < right->getVal();
      }
      

1 个答案:

答案 0 :(得分:1)

这是因为const T变为T* const,而不是T const*。一种解决方案是重新编写代码,使其不包含TT = B)中的指针,并将其包含在模板类中:

template<typename T>
class theTemplate
{
  public:
    void insert(T* val1, T* val2)
      {
        stuff[0] = val1;
        stuff[1] = val2;
      }
    bool usesSomeStaticFunction(bool (*funcp)(const T*, const T*))
      { 
        // will return true
        return funcp(stuff[0],stuff[1]);
      }
  private:
    T* stuff[2];
};