开发者

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


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;


It produces the error for const T * and not for const iterator. And the reason is that const iterator expands to T * const, not const T *.

extern int foo(int i);
extern int bar(int *i);

void baz()
{
   const int x = 5;
   int y = x;
   foo(x); // Perfectly fine
   foo(y); // Also perfectly fine
   bar(&x); // Not fine at all.
   bar(&y); // Perfectly fine.
}

void bouncy()
{
   typedef int my_t;
   typedef int *myptr_t;
   typedef const my_t const_my_t; // const (int) aka const int
   typedef const myptr_t const_myptr_t; // const (int *) aka int * const
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜