C++ function pointers inside templates

2019-06-01 02:48发布

问题:

I have this problem:

template<typename T> class Bubu
{
...
   int (*comparer)(const T t1, const T t2);
...
public:
   Bubu(int (*_comparer)(const T t1, const T t2))
   {
      comparer = _comparer;
   }
};

And in another file:

Bubu<char*> asd(strcmp);

Error:

error C2664: 'Bubu<T>::Bubu(int (__cdecl *)(const T,const T))' : 
             cannot convert parameter 1 from 'int (__cdecl *)(const char *,
             const char *)' to 'int (__cdecl *)(const T,const T)'

I don't understand why. Shouldn't the compiler see a "char*" instead of "T" there?

EDIT: the Ideone.com-ready code:


int asdf(const char* a, const char* b)
{       return 0; }

template class Bubu
{
   int (*comparer)(const T t1, const T t2);
public:
   Bubu(int (*_comparer)(const T t1, const T t2))
   {
      comparer = _comparer;
   }
};

int main(int argc, char* argv[])
{
Bubu asd(asdf);
}

回答1:

When T is char*, const T is char* const which isn't the same thing as const char *. You need:

 Bubu<const char*> asd(strcmp);

Top level const is ignored for function signatures so

int (*)( const char* const, const char* const );

is the same type as

int (*)( const char*, const char* );

so you're OK on the extra top level const although it doesn't gain you anything over the simpler int (*comparer)(T t1, T t2);.



回答2:

If T is specialized as char*, const T means char* const (i.e. immutable pointer to a mutable char), rather than const char* == char const* (i.e. mutable pointer to an immutable char).

Bubu<const char*> asd(strcmp)

will compile.



回答3:

Not sure if this is your problem, but your * in your function pointer declaration is in the wrong place (at least compared to what I've ever seen). Instead of:

int (comparer*)(const T t1, const T t2);

It should be:

int (*comparer)(const T t1, const T t2);


回答4:

I think this does what you want:

#include <cstring>
#include <iostream>

template<class T>
class Bubu {
public:
    typedef int (*Comparator)(T, T);

    Bubu(Comparator inComparator) : mComparator(inComparator) { }

    int compare(T a, T b)
    {
        return mComparator(a, b);
    }

private:
    Comparator mComparator;
};

int main() 
{
    Bubu<const char*> obj(strcmp);
    std::cout << obj.compare("one", "two") << std::endl;
    return 0;
}