15

What are the differences between using

typedef Some::Nested::Namespace::TypeName TypeName;

or

using Some::Nested::Namespace::TypeName;

to provide the shorthand TypeName in the local scope?

palm3D
  • 7,970
  • 6
  • 28
  • 33

3 Answers3

6

typedef gives an alias name for the type.

typedef Some::Nested::Namespace::TypeName TypeName;

Once you do that, You can refer Some::Nested::Namespace::TypeName just by saying TypeName in the local namespace.


using declaration makes the type visible in the current namespace.

using Some::Nested::Namespace::TypeName;

Imports the type in the current namespace.

In this case, using the either of the above you can refer Some::Nested::Namespace::TypeName by just using TypeName in the local namespace.

Alok Save
  • 202,538
  • 53
  • 430
  • 533
  • 2
    Is there a real difference though? In particular in light of the boosted C++11 `using` statement which allows defining templated aliases. – Konrad Rudolph Oct 05 '11 at 07:04
  • There is one difference for template types at least. You can only `typedef` a specialized type, such as `vector`, and you can use `using` on the unspecialized template only (`vector`, for example) – jalf Oct 05 '11 at 07:17
  • If you got a bunch of overloaded operators that you want to import, `typedef` doesn't work in this case because you have to be using `using`! – Khaled Alshaya Oct 05 '11 at 07:25
  • @AraK: `typedef` only works to alias **types** (as the name implies), so of course it does not work to import anything else. – Matthieu M. Oct 05 '11 at 07:38
6

Using just brings declaration into the local scope, while typedef introduces a typedef-name. One difference between them is elaborated type specifiers, e.g.:


namespace n
{
  class foo
  {
  };
}

typedef n::foo n_foo;

using n::foo;

int main()
{
  class foo f1; // ok, declares f1 variable of type n::foo.
  class n_foo f2; // error, typedef-name can't be used in elaborated-type-specifier.
}

Konstantin Oznobihin
  • 5,234
  • 24
  • 31
6

They have different origins and different uses.


typedef comes from C: recall that the C way to declare a struct is:

typedef struct _MyStruct { .... } MyStruct;

It allows you to introduce an alias for a type only. It can be used for the type of a function, with an awkward syntax...

typedef void (*Func)(Foo, Bar);

Where Func is now a pointer to a function taking two arguments by copy (of types Foo and Bar respectively) and returning nothing.


using has, originally, a different meaning. It is meant to inject a name into a scope. Any name (nearly) can be injected: types, functions, variables (but not enum values...)

With C++11, the syntax has been enhanced to allow template aliasing:

template <typename T>
using equiv_map = std::map<T,T>;

This powered-up using means that aliasing (see below) is now possible, on top of the previous functionalities.


This C++11 change is a clear direction toward syntax harmonization. Note how the definition of an alias is now similar to the definition of a variable:

<name> = <expression>;

Unfortunately it seems the Standard reserved this aliasing to template situations, so for now both typedef and using coexist, each with its own hunting ground.

Matthieu M.
  • 287,565
  • 48
  • 449
  • 722
  • Do you mean with your last paragraph that `using name = int;` is not well-formed in C++11? – dyp Jun 12 '13 at 06:17
  • @DyP: It is what I meant, though I cannot recall why since it does work (and is very handy for function references/pointers). I wonder if I got burned by an early version of gcc/clang. – Matthieu M. Jun 12 '13 at 06:20