3

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.

Enlico
  • 23,259
  • 6
  • 48
  • 102
  • 1
    What is "non-class memeber type"? – Evg Feb 06 '23 at 20:39
  • 1
    Do you mean that `foo::bar::baz` refers to a type that is not a member of the current class or its base classes, i.e. that `foo::bar` is not a base class? If so, https://eel.is/c++draft/namespace.udecl#3.sentence-1 simply forbids this use inside as a member declaration. – user17732522 Feb 06 '23 at 20:49
  • `using foo::bar::baz;` lets you use `baz` without qualifying it. `using baz = foo::bar::baz;` introduces a new name called `baz` that is an alias of `foo:bar::baz`. You get the same behavior (can use `baz` without qualification) but the way you get there is different. – NathanOliver Feb 06 '23 at 20:58
  • 1
    https://godbolt.org/z/77Tnh7cx9 – Language Lawyer Feb 06 '23 at 21:19
  • @Evg, what I mean is that `foo` is a namespace and `bar` is a namespace nested in it, i.e. neither of them is a class. – Enlico Feb 06 '23 at 22:11
  • @LanguageLawyer, a few words about it? – Enlico Feb 06 '23 at 22:12
  • _a few words about it?_ You mean, key references? http://eel.is/c++draft/basic.scope.scope#5 (where «denote different entities» seem to also include «one name denotes an entity, the other is a _typedef-name_») + http://eel.is/c++draft/basic.scope.scope#4.1 (or, rather, in the /(4.1)→/5 order) (I could not find normative wording saying that a _using-declarator_ introduces its _unqualified-id_, only http://eel.is/c++draft/namespace.udecl#2.sentence-2, but I think the intent is clear. Asked D. Herring) – Language Lawyer Feb 06 '23 at 22:20
  • BTW, you tag C++20, but link the current draft, which «contains» P1787 – Language Lawyer Feb 06 '23 at 22:28
  • _I could not find normative wording saying that a using-declarator introduces its unqualified-id … Asked D. Herring_ This is already known issue – Language Lawyer Feb 06 '23 at 22:48

1 Answers1

1

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.

Davis Herring
  • 36,443
  • 4
  • 48
  • 76