1

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

2
  • Must be a typo: int (*comparer)() Commented Mar 18, 2011 at 7:46
  • Tidy this up, please! I got about five unrelated errors when I tried to compile it. Then I gave up. Give us a single block of code that we can put through ideone.com! Commented Mar 18, 2011 at 7:50

4 Answers 4

9

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);.

Sign up to request clarification or add additional context in comments.

3 Comments

You're right! And I am most happy because of that. But what would happen if I'd want to change some T's inside my template? since Bubu's type has the const keyword in it?
@cantrem: You have number of options. You could write a wrapper function that calls strcmp but takes pointers to non-const char; you could template your class in the character type and not the pointer type and used int (*)( const T*, const T* ); you could use some traits-style meta functions to recover char from T = char* and manufacture const char* from there. It really depends on what your template is supposed to provide flexibility for and what it must assume about its parameters.
I went for the quick and very very dirty solution of wrapping strcmp... but since it's a school project, it deserves to be that way! I guess the best solution would be to use std::string, like normal people do.
3

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.

2 Comments

Yes, but the thing is I need that chars mutable. Any idea how to keep my Bubu<char*> declaration as it is?
To wrap strcmp into a function with non-const char* parameters is so ugly!
0

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

1 Comment

it is (at least now, sorry if it was a typo before the post edit)
0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.