Is a using declaration for a non-member type equivalent to an alias declaration with an identifier equal to the terminal name of the using declarator?

208 views Asked by At

In short, I'm asking if doing

using foo::bar::baz;

has the same effect as

using baz = foo::bar::baz;

(Clearly I'm assuming that foo::bar::baz names a type that is not a class member, e.g. I'm referring to something like namesapce foo::bar { using baz = int; }, and not to something like namespace foo { struct bar { using baz = int; }; }.)

I'm pretty sure they are two different things (otherwise they could also always stay side by side, which is not the case, as I know that the former can't be in a struct/class, unlike the latter), but how do I read it from the standard? I was looking at [namespace.udecl] and [dcl.pre], but I can't really draw a conclusion.

1

There are 1 answers

2
Davis Herring On

There are definitely differences between the two, but most of them are of no interest to most programmers. For example,

namespace N {
  struct X {};
  struct Y {};
  struct Z {};
}
namespace O {
  int X,Y;
  using N::X;    // OK
  struct X x;    // OK, finds N::X
  int i=X;       // OK, finds O::X
  using Y=N::Y;  // error: conflicts with “int Y”
  using Z=N::Z;
  struct Z z;    // error: elaborated-type-specifier with typedef-name
}

One practical distinction is in exporting a previously declared name with module linkage:

module A:S;
struct S {};
export module A;
import :S;
export using ::S;  // error: “struct S” has module linkage
export using S=S;  // OK

The using-declaration can of course also be applied to non-type declarations, whereas the alias-declaration can also be a template.