[namespace.udecl] # 9 Declarations [[dcl]](./#dcl) ## 9.10 The using declaration [namespace.udecl] [using-declaration:](#nt:using-declaration "9.10 The using declaration [namespace.udecl]") using [*using-declarator-list*](#nt:using-declarator-list "9.10 The using declaration [namespace.udecl]") ; [using-declarator-list:](#nt:using-declarator-list "9.10 The using declaration [namespace.udecl]") [*using-declarator*](#nt:using-declarator "9.10 The using declaration [namespace.udecl]") ...opt [*using-declarator-list*](#nt:using-declarator-list "9.10 The using declaration [namespace.udecl]") , [*using-declarator*](#nt:using-declarator "9.10 The using declaration [namespace.udecl]") ...opt [using-declarator:](#nt:using-declarator "9.10 The using declaration [namespace.udecl]") typenameopt [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") [*unqualified-id*](expr.prim.id.unqual#nt:unqualified-id "7.5.5.2 Unqualified names [expr.prim.id.unqual]") [1](#1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L8687) The component names of a [*using-declarator*](#nt:using-declarator "9.10 The using declaration [namespace.udecl]") are those of its [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") and [*unqualified-id*](expr.prim.id.unqual#nt:unqualified-id "7.5.5.2 Unqualified names [expr.prim.id.unqual]")[.](#1.sentence-1) Each [*using-declarator*](#nt:using-declarator "9.10 The using declaration [namespace.udecl]") in a [*using-declaration*](#nt:using-declaration "9.10 The using declaration [namespace.udecl]")[84](#footnote-84 "A using-declaration with more than one using-declarator is equivalent to a corresponding sequence of using-declarations with one using-declarator each.") names the set of declarations found by lookup ([[basic.lookup.qual]](basic.lookup.qual "6.5.5 Qualified name lookup")) for the [*using-declarator*](#nt:using-declarator "9.10 The using declaration [namespace.udecl]"), except that class and enumeration declarations that would be discarded are merely ignored when checking for ambiguity ([[basic.lookup]](basic.lookup "6.5 Name lookup")), conversion function templates with a dependent return type are ignored, and certain functions are hidden as described below[.](#1.sentence-2) If the terminal name of the [*using-declarator*](#nt:using-declarator "9.10 The using declaration [namespace.udecl]") is dependent ([[temp.dep.type]](temp.dep.type "13.8.3.2 Dependent types")), the [*using-declarator*](#nt:using-declarator "9.10 The using declaration [namespace.udecl]") is considered to name a constructor if and only if the [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") has a terminal name that is the same as the [*unqualified-id*](expr.prim.id.unqual#nt:unqualified-id "7.5.5.2 Unqualified names [expr.prim.id.unqual]")[.](#1.sentence-3) If the lookup in any instantiation finds that a [*using-declarator*](#nt:using-declarator "9.10 The using declaration [namespace.udecl]") that is not considered to name a constructor does do so, or that a [*using-declarator*](#nt:using-declarator "9.10 The using declaration [namespace.udecl]") that is considered to name a constructor does not, the program is ill-formed[.](#1.sentence-4) [2](#2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L8716) If the [*using-declarator*](#nt:using-declarator "9.10 The using declaration [namespace.udecl]") names a constructor, it declares that the class [*inherits*](#def:constructor,inherited "9.10 The using declaration [namespace.udecl]") the named set of constructor declarations from the nominated base class[.](#2.sentence-1) [*Note [1](#note-1)*: Otherwise, the [*unqualified-id*](expr.prim.id.unqual#nt:unqualified-id "7.5.5.2 Unqualified names [expr.prim.id.unqual]") in the [*using-declarator*](#nt:using-declarator "9.10 The using declaration [namespace.udecl]") is bound to the [*using-declarator*](#nt:using-declarator "9.10 The using declaration [namespace.udecl]"), which is replaced during name lookup with the declarations it names ([[basic.lookup]](basic.lookup "6.5 Name lookup"))[.](#2.sentence-2) If such a declaration is of an enumeration, the names of its enumerators are not bound[.](#2.sentence-3) For the keyword typename, see [[temp.res]](temp.res "13.8 Name resolution")[.](#2.sentence-4) — *end note*] [3](#3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L8732) In a [*using-declaration*](#nt:using-declaration "9.10 The using declaration [namespace.udecl]") used as a[*member-declaration*](class.mem.general#nt:member-declaration "11.4.1 General [class.mem.general]"), each [*using-declarator*](#nt:using-declarator "9.10 The using declaration [namespace.udecl]") shall either name an enumerator or have a [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") naming a base class of the current class ([[expr.prim.this]](expr.prim.this "7.5.3 This"))[.](#3.sentence-1) [*Example [1](#example-1)*: enum class button { up, down };struct S {using button::up; button b = up; // OK}; — *end example*] If a[*using-declarator*](#nt:using-declarator "9.10 The using declaration [namespace.udecl]") names a constructor, its [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") shall name a direct base class of the current class[.](#3.sentence-2) If the immediate (class) scope is associated with a class template, it shall derive from the specified base class or have at least one dependent base class[.](#3.sentence-3) [*Example [2](#example-2)*: struct B {void f(char); enum E { e }; union { int x; };}; struct C {int f();}; struct D : B {using B::f; // OK, B is a base of Dusing B::e; // OK, e is an enumerator of base Busing B::x; // OK, x is a union member of base Busing C::f; // error: C isn't a base of Dvoid f(int) { f('c'); } // calls B​::​f(char)void g(int) { g('c'); } // recursively calls D​::​g(int)};template struct X : bases... {using bases::f...;}; X x; // OK, B​::​f and C​::​f named — *end example*] [4](#4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L8783) [*Note [2](#note-2)*: Since destructors do not have names, a[*using-declaration*](#nt:using-declaration "9.10 The using declaration [namespace.udecl]") cannot refer to a destructor for a base class[.](#4.sentence-1) — *end note*] If a constructor or assignment operator brought from a base class into a derived class has the signature of a copy/move constructor or assignment operator for the derived class ([[class.copy.ctor]](class.copy.ctor "11.4.5.3 Copy/move constructors"), [[class.copy.assign]](class.copy.assign "11.4.6 Copy/move assignment operator")), the [*using-declaration*](#nt:using-declaration "9.10 The using declaration [namespace.udecl]") does not by itself suppress the implicit declaration of the derived class member; the member from the base class is hidden or overridden by the implicitly-declared copy/move constructor or assignment operator of the derived class, as described below[.](#4.sentence-2) [5](#5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L8798) A [*using-declaration*](#nt:using-declaration "9.10 The using declaration [namespace.udecl]") shall not name a [*template-id*](temp.names#nt:template-id "13.3 Names of template specializations [temp.names]")[.](#5.sentence-1) [*Example [3](#example-3)*: struct A {template void f(T); template struct X { };};struct B : A {using A::f; // errorusing A::X; // error}; — *end example*] [6](#6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L8813) A [*using-declaration*](#nt:using-declaration "9.10 The using declaration [namespace.udecl]") shall not name a namespace[.](#6.sentence-1) [7](#7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L8816) A [*using-declaration*](#nt:using-declaration "9.10 The using declaration [namespace.udecl]") that names a class member other than an enumerator shall be a[*member-declaration*](class.mem.general#nt:member-declaration "11.4.1 General [class.mem.general]")[.](#7.sentence-1) [*Example [4](#example-4)*: struct X {int i; static int s;}; void f() {using X::i; // error: X​::​i is a class member and this is not a member declaration.using X::s; // error: X​::​s is a class member and this is not a member declaration.} — *end example*] [8](#8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L8835) If a declaration is named by two [*using-declarator*](#nt:using-declarator "9.10 The using declaration [namespace.udecl]")*s* that inhabit the same class scope, the program is ill-formed[.](#8.sentence-1) [*Example [5](#example-5)*: struct C {int i;}; struct D1 : C { };struct D2 : C { }; struct D3 : D1, D2 {using D1::i; // OK, equivalent to using C​::​iusing D1::i; // error: duplicateusing D2::i; // error: duplicate, also names C​::​i}; — *end example*] [9](#9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L8855) [*Note [3](#note-3)*: A [*using-declarator*](#nt:using-declarator "9.10 The using declaration [namespace.udecl]") whose [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") names a namespace does not name declarations added to the namespace after it[.](#9.sentence-1) Thus, additional overloads added after the [*using-declaration*](#nt:using-declaration "9.10 The using declaration [namespace.udecl]") are ignored, but default function arguments ([[dcl.fct.default]](dcl.fct.default "9.3.4.7 Default arguments")), default template arguments ([[temp.param]](temp.param "13.2 Template parameters")), and template specializations ([[temp.spec.partial]](temp.spec.partial "13.7.6 Partial specialization"), [[temp.expl.spec]](temp.expl.spec "13.9.4 Explicit specialization")) are considered[.](#9.sentence-2) — *end note*] [*Example [6](#example-6)*: namespace A {void f(int);}using A::f; // f is a synonym for A​::​f; that is, for A​::​f(int).namespace A {void f(char);}void foo() { f('a'); // calls f(int), even though f(char) exists.}void bar() {using A::f; // f is a synonym for A​::​f; that is, for A​::​f(int) and A​::​f(char). f('a'); // calls f(char)} — *end example*] [10](#10) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L8887) If a declaration named by a [*using-declaration*](#nt:using-declaration "9.10 The using declaration [namespace.udecl]") that inhabits the target scope of another declaration B potentially conflicts with it ([[basic.scope.scope]](basic.scope.scope "6.4.1 General")), and either is reachable from the other, the program is ill-formed unless B is name-independent and the [*using-declaration*](#nt:using-declaration "9.10 The using declaration [namespace.udecl]") precedes B[.](#10.sentence-1) [*Example [7](#example-7)*: int _;void f() {int _; // B _ = 0; using ::_; // error: [*using-declaration*](#nt:using-declaration "9.10 The using declaration [namespace.udecl]") does not precede B} — *end example*] If two declarations named by [*using-declaration*](#nt:using-declaration "9.10 The using declaration [namespace.udecl]")*s* that inhabit the same scope potentially conflict, either is reachable from the other, and they do not both declare functions or function templates, the program is ill-formed[.](#10.sentence-2) [*Note [4](#note-4)*: Overload resolution possibly cannot distinguish between conflicting function declarations[.](#10.sentence-3) — *end note*] [*Example [8](#example-8)*: namespace A {int x; int f(int); int g; void h();}namespace B {int i; struct g { }; struct x { }; void f(int); void f(double); void g(char); // OK, hides struct g}void func() {int i; using B::i; // error: conflictsvoid f(char); using B::f; // OK, each f is a functionusing A::f; // OK, but interferes with B​::​f(int) f(1); // error: ambiguousstatic_cast(f)(1); // OK, calls A​::​f f(3.5); // calls B​::​f(double)using B::g; g('a'); // calls B​::​g(char)struct g g1; // g1 has class type B​::​gusing A::g; // error: conflicts with B​::​gvoid h(); using A::h; // error: conflictsusing B::x; using A::x; // OK, hides struct B​::​xusing A::x; // OK, does not conflict with previous using A​::​x x = 99; // assigns to A​::​xstruct x x1; // x1 has class type B​::​x} — *end example*] [11](#11) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L8955) The set of declarations named by a [*using-declarator*](#nt:using-declarator "9.10 The using declaration [namespace.udecl]") that inhabits a class C does not include member functions and member function templates of a base class that correspond to (and thus would conflict with) a declaration of a function or function template in C[.](#11.sentence-1) [*Example [9](#example-9)*: struct B {virtual void f(int); virtual void f(char); void g(int); void h(int);}; struct D : B {using B::f; void f(int); // OK, D​::​f(int) overrides B​::​f(int);using B::g; void g(char); // OKusing B::h; void h(int); // OK, D​::​h(int) hides B​::​h(int)}; void k(D* p){ p->f(1); // calls D​::​f(int) p->f('a'); // calls B​::​f(char) p->g(1); // calls B​::​g(int) p->g('a'); // calls D​::​g(char)}struct B1 { B1(int);}; struct B2 { B2(int);}; struct D1 : B1, B2 {using B1::B1; using B2::B2;}; D1 d1(0); // error: ambiguousstruct D2 : B1, B2 {using B1::B1; using B2::B2; D2(int); // OK, D2​::​D2(int) hides B1​::​B1(int) and B2​::​B2(int)}; D2 d2(0); // calls D2​::​D2(int) — *end example*] [12](#12) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L9013) [*Note [5](#note-5)*: For the purpose of forming a set of candidates during overload resolution, the functions named by a [*using-declaration*](#nt:using-declaration "9.10 The using declaration [namespace.udecl]") in a derived class are treated as though they were direct members of the derived class[.](#12.sentence-1) In particular, the implicit object parameter is treated as if it were a reference to the derived class rather than to the base class ([[over.match.funcs]](over.match.funcs "12.2.2 Candidate functions and argument lists"))[.](#12.sentence-2) This has no effect on the type of the function, and in all other respects the function remains part of the base class[.](#12.sentence-3) — *end note*] [13](#13) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L9026) Constructors that are named by a [*using-declaration*](#nt:using-declaration "9.10 The using declaration [namespace.udecl]") are treated as though they were constructors of the derived class when looking up the constructors of the derived class ([[class.qual]](class.qual "6.5.5.2 Class members")) or forming a set of overload candidates ([[over.match.ctor]](over.match.ctor "12.2.2.4 Initialization by constructor"), [[over.match.copy]](over.match.copy "12.2.2.5 Copy-initialization of class by user-defined conversion"), [[over.match.list]](over.match.list "12.2.2.8 Initialization by list-initialization"))[.](#13.sentence-1) [*Note [6](#note-6)*: If such a constructor is selected to perform the initialization of an object of class type, all subobjects other than the base class from which the constructor originated are implicitly initialized ([[class.inhctor.init]](class.inhctor.init "11.9.4 Initialization by inherited constructor"))[.](#13.sentence-2) A constructor of a derived class is sometimes preferred to a constructor of a base class if they would otherwise be ambiguous ([[over.match.best]](over.match.best "12.2.4 Best viable function"))[.](#13.sentence-3) — *end note*] [14](#14) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L9040) In a [*using-declarator*](#nt:using-declarator "9.10 The using declaration [namespace.udecl]") that does not name a constructor, every declaration named shall be accessible[.](#14.sentence-1) In a [*using-declarator*](#nt:using-declarator "9.10 The using declaration [namespace.udecl]") that names a constructor, no access check is performed[.](#14.sentence-2) [15](#15) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L9047) [*Note [7](#note-7)*: Because a [*using-declarator*](#nt:using-declarator "9.10 The using declaration [namespace.udecl]") designates a base class member (and not a member subobject or a member function of a base class subobject), a [*using-declarator*](#nt:using-declarator "9.10 The using declaration [namespace.udecl]") cannot be used to resolve inherited member ambiguities[.](#15.sentence-1) [*Example [10](#example-10)*: struct A { int x(); };struct B : A { };struct C : A {using A::x; int x(int);}; struct D : B, C {using C::x; int x(double);};int f(D* d) {return d->x(); // error: overload resolution selects A​::​x, but A is an ambiguous base class} — *end example*] — *end note*] [16](#16) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L9073) A [*using-declaration*](#nt:using-declaration "9.10 The using declaration [namespace.udecl]") has the usual accessibility for a [*member-declaration*](class.mem.general#nt:member-declaration "11.4.1 General [class.mem.general]")[.](#16.sentence-1) Base-class constructors considered because of a [*using-declarator*](#nt:using-declarator "9.10 The using declaration [namespace.udecl]") are accessible if they would be accessible when used to construct an object of the base class; the accessibility of the [*using-declaration*](#nt:using-declaration "9.10 The using declaration [namespace.udecl]") is ignored[.](#16.sentence-2) [*Example [11](#example-11)*: class A {private:void f(char);public:void f(int);protected:void g();}; class B : public A {using A::f; // error: A​::​f(char) is inaccessiblepublic:using A::g; // B​::​g is a public synonym for A​::​g}; — *end example*] [84)](#footnote-84)[84)](#footnoteref-84) A [*using-declaration*](#nt:using-declaration "9.10 The using declaration [namespace.udecl]") with more than one[*using-declarator*](#nt:using-declarator "9.10 The using declaration [namespace.udecl]") is equivalent to a corresponding sequence of [*using-declaration*](#nt:using-declaration "9.10 The using declaration [namespace.udecl]")*s* with one [*using-declarator*](#nt:using-declarator "9.10 The using declaration [namespace.udecl]") each[.](#footnote-84.sentence-1)