Typedef allows redefinition of names?

K

Ken Camann

I was a bit surprised to find that my compiler (MSVC++) actually
accepts the following as legal. It cleans up the code very nicely,
but I am sort of confused about some of the finer points of how the
naming and template systems interact in a compiler. Does the
following always work?

In Vector3.h, I have this class

namespace Geometry {

termplate<typename NumericType>
class Vector3
{
....
};

}

In another file, Triangle.h, I have

#include <Vector3.h>

namespace Geometry {

template<typename NumericType>
class Triangle
{
public:
typedef Vector3<NumericType> Vector3;

//Then I go on to use Vector3 instead of Vector3<NumericType>
};

}

Like I said, I was pretty surprised it let me take the "root" part of
the template name Vector3<NumericType> and redefine it as a specific
type, namely the specific type that inherits the template type from
the class that it belongs to. Needless to say, if I type in
Vector3<NumericType> after the typedef this produces an error, since
the symbol Vector3 = Vector3<NumericType> already.

Thanks for your time,
Ken
 
J

Joe Greer

I was a bit surprised to find that my compiler (MSVC++) actually
accepts the following as legal. It cleans up the code very nicely,
but I am sort of confused about some of the finer points of how the
naming and template systems interact in a compiler. Does the
following always work?

In Vector3.h, I have this class

namespace Geometry {

termplate<typename NumericType>
class Vector3
{
...
};

}

In another file, Triangle.h, I have

#include <Vector3.h>

namespace Geometry {

template<typename NumericType>
class Triangle
{
public:
typedef Vector3<NumericType> Vector3;

//Then I go on to use Vector3 instead of Vector3<NumericType>
};

}

Like I said, I was pretty surprised it let me take the "root" part of
the template name Vector3<NumericType> and redefine it as a specific
type, namely the specific type that inherits the template type from
the class that it belongs to. Needless to say, if I type in
Vector3<NumericType> after the typedef this produces an error, since
the symbol Vector3 = Vector3<NumericType> already.

Interesting...

I suspect that it is because there is no Vector3 defined at that scope
(within the class). So, what you have defined is Geometry::Triangle
<NumericType>::Vector3 and that doesn't conflict with Geometry::Vector3
<>.

joe
 
V

Victor Bazarov

Ken said:
I was a bit surprised to find that my compiler (MSVC++) actually
accepts the following as legal. It cleans up the code very nicely,
but I am sort of confused about some of the finer points of how the
naming and template systems interact in a compiler. Does the
following always work?

In Vector3.h, I have this class

namespace Geometry {

termplate<typename NumericType>
class Vector3
{
...
};

}

In another file, Triangle.h, I have

#include <Vector3.h>

namespace Geometry {

template<typename NumericType>
class Triangle
{
public:
typedef Vector3<NumericType> Vector3;

//Then I go on to use Vector3 instead of Vector3<NumericType>
};

}

Like I said, I was pretty surprised it let me take the "root" part of
the template name Vector3<NumericType> and redefine it as a specific
type, namely the specific type that inherits the template type from
the class that it belongs to. Needless to say, if I type in
Vector3<NumericType> after the typedef this produces an error, since
the symbol Vector3 = Vector3<NumericType> already.

I believe it's OK to do that (just like you can define an object of
type 'S' and call it 'S'), but I doubt it's a good idea. I would
recommend using a different identifier for the typedef-name.

V
 
P

Paul Brettschneider

Victor said:
I believe it's OK to do that (just like you can define an object of
type 'S' and call it 'S'), but I doubt it's a good idea.  I would
recommend using a different identifier for the typedef-name.

Hmmm...
This:
template<typename T> class Test {
typedef Test Test<T>;
Test t;
};

does not compile on the g++ version on my computer (v4.1.3):
test.C:2: error: ISO C++ forbids nested type ‘Test’ with same name as
enclosing class
test.C:2: error: ‘Test<T>::Test’ has the same name as the class in which it
is declared
 
P

Paul Brettschneider

Paul said:
Hmmm...
This:
template<typename T> class Test {
typedef Test Test<T>;
Test t;
};

does not compile on the g++ version on my computer (v4.1.3):
test.C:2: error: ISO C++ forbids nested type ‘Test’ with same name as
enclosing class
test.C:2: error: ‘Test<T>::Test’ has the same name as the class in which
it is declared

This, on the other hand, does:
template<typename T> class Test {
T t;
};

template<typename T> class Test2 {
typedef Test<T> Test;
Test t;
};
 
P

Paul Brettschneider

Paul said:
Hmmm...
This:
template<typename T> class Test {
typedef Test Test<T>;
Test t;
};

Ouch. This is so wrong it hurts:
* typedef the wrong way 'round.
* class with itself as member object.
Sorry for the noise. I will try to think before posting next time. :/
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,197
Messages
2,571,040
Members
47,634
Latest member
RonnyBoelk

Latest Threads

Top