[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 <typename... bases>struct X : bases... {using bases::f...;};
X<B, C> 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 <class T> void f(T); template <class T> struct X { };};struct B : A {using A::f<double>; // errorusing A::X<int>; // 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<int(*)(int)>(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)
