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.