typedefs vs. using-declarations

P

pyramus

I am wondering which one should be preferred for creating a local
synonym within a function definition. Let's say I have a type in my
library called MyLib::Foundation::int32, which I can't stand typing all
the time. Should I do:

void foo()
{
typedef MyLib::Foundation::int32 int32;
int32 x = 0;
}

OR:

void bar()
{
using MyLib::Foundation::int32;
int32 x = 0;
}

First, is there any difference between the two, according to the
language standard? A colleague has suggested that typedef would
"override" any other definitions of int32 that might exist, while a
using-declaration may not, but he wasn't sure about this.

If there is a difference, would there be one that you'd prefer as a best
practice? (When restricted to local use within function definitions.)

Thanks in advance
 
V

Victor Bazarov

pyramus said:
I am wondering which one should be preferred for creating a local
synonym within a function definition. Let's say I have a type in my
library called MyLib::Foundation::int32, which I can't stand typing
all the time. Should I do:

void foo()
{
typedef MyLib::Foundation::int32 int32;
int32 x = 0;
}

OR:

void bar()
{
using MyLib::Foundation::int32;
int32 x = 0;
}

First, is there any difference between the two, according to the
language standard? A colleague has suggested that typedef would
"override" any other definitions of int32 that might exist, while a
using-declaration may not, but he wasn't sure about this.

No, it won't "override". It will _hide_. And a using declaration
will actually introduce a conflict, an ambiguity, IIRC. Just test
it with your favourite compiler.
If there is a difference, would there be one that you'd prefer as a
best practice? (When restricted to local use within function
definitions.)

There is no essential difference to the code that uses it. Of course,
if you for some reason change 'int32' from being a type to being
an object, then 'using' should still compile, while 'typedef' should
definitely fail.

V
 
P

pyramus

Victor said:
No, it won't "override". It will _hide_. And a using declaration
will actually introduce a conflict, an ambiguity, IIRC. Just test
it with your favourite compiler.

Oops, yeah, "hide" is the correct term. I tested this on my compiler
(VC2003) and found that both typedefs and using-declarations produced
similar results. If they referred to two different things, then the
compiler would produce an error.

If the using-declaration comes after the typedef:
error C2874: using-declaration causes a multiple declaration of
'MyLib::Foundation::int32'

If the typedef comes after the using-declaration:
error C2371: 'MyLib::Foundation::int32' : redefinition; different basic
types

However, if both referred to the same thing, the compiler did not
produce an error or warning. So it looks to me like there is little or
no practical difference between the two in terms of name look up.
According to section 3.4.1 of the standard,

"The name look up rules apply uniformly to all names (including
typedef-names, namespace-names and class-names) wherever the grammar
allows such names in the context discussed by a particular rule."
There is no essential difference to the code that uses it. Of course,
if you for some reason change 'int32' from being a type to being
an object, then 'using' should still compile, while 'typedef' should
definitely fail.

Why? Let's say you changed int32 to:

namespace MyLib
{
namespace Foundation
{
class int32 { ... };
}
}

Then would it make any difference whether you used

typedef MyLib::Foundation::int32 int32;

or

using MyLib::Foundation::int32;

In either case, 'int32' would just become a synonym for the same class
name, right?

Thanks again
 
V

Victor Bazarov

pyramus said:
Victor said:
[...]
There is no essential difference to the code that uses it. Of course,
if you for some reason change 'int32' from being a type to being
an object, then 'using' should still compile, while 'typedef' should
definitely fail.

Why? Let's say you changed int32 to:

namespace MyLib
{
namespace Foundation
{
class int32 { ... };
}
}

Then would it make any difference whether you used

typedef MyLib::Foundation::int32 int32;

or

using MyLib::Foundation::int32;

In either case, 'int32' would just become a synonym for the same class
name, right?

Right. But now, change it to

namespace MyLib
{
namespace Foundation
{
const int int32 = 32; // an object
}
}

V
 

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

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,564
Members
45,039
Latest member
CasimiraVa

Latest Threads

Top