Template class method specialization fails when type is a pointer

Viewed 50

I have a template class called Vector and I want to specialize one of its methods called my_compare depending on the type that the class takes in. I am able to successfully specialize it for most types, however the specialization will not compile if I am using a pointer type.

At top of cpp file:

template <typename T> class Vector {
public: 
...
  bool my_compare(const T a, const T b);
...
};

Later on:

template <typename T> bool Vector<T>::my_compare(const T a, const T b){
  return (a < b);
}
template <> bool Vector<Mystring>::my_compare(const Mystring a, const Mystring b){
  //cout << "did a mycompare for stringies";
  return (strcmp(a.c_str(), b.c_str()) > 0);
}
template <> bool Vector<char*>::my_compare(const char* a, const char* b){
  return (strcmp(a, b) > 0);
}

The specialization works for Mystring but not for char*. I get the following error:

iterator.cpp:106:18: error: template-id ‘my_compare<>’ for ‘bool Vector<char*>::my_compare(const char*, const char*)’ does not match any template declaration
 template <> bool Vector<char*>::my_compare(const char* a, const char* b){
                  ^~~~~~~~~~~~~

The compiler spits the same error when I use different pointer types, like int* or Mystring*. I am using G++ as the compiler. Anyone know what I'm doing wrong and how I can fix it? Thanks for the help!

1 Answers

It's a little subtle, but it's because const char* is not the same as char* const.

Your function my_compare(const T a, const T b) expects a const T. T in this case is char*. So you want a constant pointer not a pointer to a constant.

The rules for adding qualifiers allow you to put const and volatile to the left of the type, even though most modifiers are applied right to left. To put another, you are defining:

my_compare(char const* a, char const* b)

Instead of:

my_compare(char* const a, char* const b)

Some other references to see:

https://en.wikipedia.org/wiki/Const_(computer_programming)

When reading to the left, it is important that you read the elements from right to left. So an int const * becomes a pointer to a const int and not a const pointer to an int.

Related