Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does typedef affect function overloads?

I have two functions in a class (please comment on the issue and not the coding style):

template <typename T>
class myStringClass
{
public:
  ...

  typedef T* iterator;

  void erase(size_t pos, size_t n); // FUNC#1
  void erase(iterator first, iterator last); //FUNC#2
};

FUNC#2 is erasing the range while FUNC#1 simply calls FUNC#2 after calculating the appropriate range. In FUNC#1 instead of declaring iterator to calculate the range, I declared T* which is (should be?) essentially the same thing.

// SEGMENT#1 in function erase(size_t pos, size_t n)
T* begin = m_begin + pos;
T* end = begin + n;
erase(begin, end); // call FUNC#2

However, this does not compile. The compiler complains that it cannot convert T* (where T is a char) to size_t (i.e. trying to call `FUNC#1). But if I change the above code to:

// SEGMENT#2 in function erase(size_t pos, size_t n)
iterator begin = m_begin + pos;
iterator end = begin + n;
erase(begin, end); // call FUNC#2

Then the compiler is happy. I assumed that typedef was an alias and was not type-checked. So SEGMENT#1 == SEGMENT#1 as far as the compiler is concerned? Why does one compile and the other doesn't?


EDIT: After testing Oli's code, I checked it against mine and I forgot to add const to the iterators in SEGMENT#2. Aside from the argument that adding const does not make sense in this case, why does that produce the error for T* and not iterator. Here is Oli's code slightly modified if you want to give it a try:

#include <stdlib.h>

template <typename T>
class myStringClass
{
private:
  T *m_begin;

public:

  typedef T* iterator;

  void erase(size_t pos, size_t n); // FUNC#1
  void erase(iterator first, iterator last); //FUNC#2
};


template <typename T>
void myStringClass<T>::erase(size_t pos, size_t n)
{
  const T* begin = m_begin + pos; // replace with iterator to compile
  const T* end = begin + n; // replace with iterator to compile
  erase(begin, end); // call the overload
}


template <typename T>
void myStringClass<T>::erase(const iterator first, const iterator last)
{
}

int main(void)
{
  myStringClass<char> x;
  x.erase(1,1);
}
like image 592
Samaursa Avatar asked Jan 01 '26 11:01

Samaursa


1 Answers

The following code compiles fine:

#include <stdlib.h>

template <typename T>
class myStringClass
{
private:
  T *m_begin;

public:

  typedef T* iterator;

  void erase(size_t pos, size_t n); // FUNC#1
  void erase(iterator first, iterator last); //FUNC#2
};


template <typename T>
void myStringClass<T>::erase(size_t pos, size_t n)
{
    T* begin = m_begin + pos;
    T* end = begin + n;
    erase(begin, end); // call the overload
}


template <typename T>
void myStringClass<T>::erase(iterator first, iterator last)
{
}


int main(void)
{
    myStringClass<char> x;
    x.erase(1,1);
}

Your problem must be elsewhere.

UPDATE

Now you've shown your real code...

The problem is you're trying to call a function that takes non-const pointers by passing it const pointers. This isn't valid.

UPDATE 2

Now that you've shown your "real real" code...

The problem is that this:

typedef T *U;
const U x;

is not the same as:

const T *x;

it's actually the same as:

T *const x;
like image 64
Oliver Charlesworth Avatar answered Jan 03 '26 02:01

Oliver Charlesworth



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!