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



我搜索了谷歌和stackoverflow,但找不到解决这种情况的东西:

  1. 我有一个带有方法的模板,该方法使用函数指针
  2. 函数指针本身不是一个模板,它是一个普通的函数指针
  3. 然而,函数指针的参数中使用了模板参数

文件名: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("%dn", 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

感谢您的帮助

更新

事实证明,有一个更好的解决方案-只需在静态函数中将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();
}
这是因为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];
};

最新更新