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
}
精彩评论