Working Draft, Standard for Programming Language C++ (N4713, 2017 year) - page 10

 

  Главная      Manuals     Working Draft, Standard for Programming Language C++ (N4713, 2017 year)

 

Search            copyright infringement  

 

 

 

 

 

 

 

 

 

 

 

Content      ..     8      9      10      11     ..

 

 

 

Working Draft, Standard for Programming Language C++ (N4713, 2017 year) - page 10

 

 

A a;
// OK: calls A::A()
const B b;
// error: B has no default constructor
int i;
// OK: i has indeterminate value
int j = 5;
// OK: j has the value 5
};
— end example ]
10
If a given non-static data member has both a default member initializer and a mem-initializer, the initialization
specified by the mem-initializer is performed, and the non-static data member’s default member initializer is
ignored. [ Example: Given
struct A {
int i = /∗ some integer expression with side effects ∗/ ;
A(int arg) : i(arg) { }
// ...
};
the A(int) constructor will simply initialize i to the value of arg, and the side effects in i’s default member
initializer will not take place.
— end example ]
11
A temporary expression bound to a reference member from a default member initializer is ill-formed.
[ Example:
struct A {
A() = default;
// OK
A(int v) : v(v) { }
// OK
const int& v = 42;
// OK
};
A a1;
// error: ill-formed binding of temporary to reference
A a2(1);
// OK, unfortunately
— end example ]
12
In a non-delegating constructor, the destructor for each potentially constructed subobject of class type is
potentially invoked (15.4). [ Note: This provision ensures that destructors can be called for fully-constructed
subobjects in case an exception is thrown (18.2).
— end note ]
13
In a non-delegating constructor, initialization proceeds in the following order:
(13.1)
First, and only for the constructor of the most derived class (6.6.2), virtual base classes are initialized in
the order they appear on a depth-first left-to-right traversal of the directed acyclic graph of base classes,
where “left-to-right” is the order of appearance of the base classes in the derived class base-specifier-list.
(13.2)
Then, direct base classes are initialized in declaration order as they appear in the base-specifier-list
(regardless of the order of the mem-initializer s).
(13.3)
Then, non-static data members are initialized in the order they were declared in the class definition
(again regardless of the order of the mem-initializer s).
(13.4)
Finally, the compound-statement of the constructor body is executed.
[ Note: The declaration order is mandated to ensure that base and member subobjects are destroyed in the
reverse order of initialization.
— end note ]
14
[ Example:
struct V {
V();
V(int);
};
struct A : virtual V {
A();
A(int);
};
struct B : virtual V {
B();
B(int);
};
§ 15.6.2
262
struct C : A, B, virtual V {
C();
C(int);
};
A::A(int i) : V(i) { /* ... */ }
B::B(int i) { /* ... */ }
C::C(int i) { /* ... */ }
V v(1);
// use V(int)
A a(2);
// use V(int)
B b(3);
// use V()
C c(4);
// use V()
— end example ]
15
Names in the expression-list or braced-init-list of a mem-initializer are evaluated in the scope of the constructor
for which the mem-initializer is specified. [ Example:
class X {
int a;
int b;
int i;
int j;
public:
const int& r;
X(int i): r(a), b(i), i(i), j(this->i) { }
};
initializes X::r to refer to X::a, initializes X::b with the value of the constructor parameter i, initializes X::i
with the value of the constructor parameter i, and initializes X::j with the value of X::i; this takes place
each time an object of class X is created.
— end example ] [ Note: Because the mem-initializer are evaluated
in the scope of the constructor, the this pointer can be used in the expression-list of a mem-initializer to
refer to the object being initialized.
— end note ]
16
Member functions (including virtual member functions, 13.3) can be called for an object under construction.
Similarly, an object under construction can be the operand of the typeid operator (8.5.1.8) or of a dynamic_-
cast (8.5.1.7). However, if these operations are performed in a ctor-initializer (or in a function called directly
or indirectly from a ctor-initializer) before all the mem-initializers for base classes have completed, the
program has undefined behavior. [ Example:
class A {
public:
A(int);
};
class B : public A {
int j;
public:
int f();
B() : A(f()),
// undefined: calls member function but base A not yet initialized
j(f()) { }
// well-defined: bases are all initialized
};
class C {
public:
C(int);
};
class D : public B, C {
int i;
public:
D() : C(f()),
// undefined: calls member function but base C not yet initialized
i(f()) { }
// well-defined: bases are all initialized
};
— end example ]
§ 15.6.2
263
17
[ Note: 15.7 describes the result of virtual function calls, typeid and dynamic_casts during construction for
the well-defined cases; that is, describes the polymorphic behavior of an object under construction.
— end
note ]
18
A mem-initializer followed by an ellipsis is a pack expansion (17.6.3) that initializes the base classes specified
by a pack expansion in the base-specifier-list for the class. [ Example:
template<class... Mixins>
class X : public Mixins... {
public:
X(const Mixins&... mixins) : Mixins(mixins)... { }
};
— end example ]
15.6.3
Initialization by inherited constructor
[class.inhctor.init]
1
When a constructor for type B is invoked to initialize an object of a different type D (that is, when the
constructor was inherited (10.3.3)), initialization proceeds as if a defaulted default constructor were used to
initialize the D object and each base class subobject from which the constructor was inherited, except that
the B subobject is initialized by the invocation of the inherited constructor. The complete initialization is
considered to be a single function call; in particular, the initialization of the inherited constructor’s parameters
is sequenced before the initialization of any part of the D object. [ Example:
struct B1 {
B1(int, ...) { }
};
struct B2 {
B2(double) { }
};
int get();
struct D1 : B1 {
using B1::B1;
// inherits B1(int, ...)
int x;
int y = get();
};
void test() {
D1 d(2, 3, 4);
// OK: B1 is initialized by calling B1(2, 3, 4),
// then d.x is default-initialized (no initialization is performed),
// then d.y is initialized by calling get()
D1 e;
// error: D1 has a deleted default constructor
}
struct D2 : B2 {
using B2::B2;
B1 b;
};
D2 f(1.0);
// error: B1 has a deleted default constructor
struct W { W(int);
};
struct X : virtual
W {
using W::W; X() = delete; };
struct Y : X { using X::X; };
struct Z : Y, virtual W { using Y::Y; };
Z z(0);
// OK: initialization of Y does not invoke default constructor of
X
template<class T> struct Log : T {
using T::T;
// inherits all constructors from class T
~Log() { std::clog << "Destroying wrapper" << std::endl; }
};
§ 15.6.3
264
Class template Log wraps any class and forwards all of its constructors, while writing a message to the
standard log whenever an object of class Log is destroyed.
— end example ]
2
If the constructor was inherited from multiple base class subobjects of type B, the program is ill-formed.
[ Example:
struct A { A(int); };
struct B : A { using A::A; };
struct C1 : B { using B::B; };
struct C2 : B { using B::B; };
struct D1 : C1, C2 {
using C1::C1;
using C2::C2;
};
struct V1 : virtual B { using B::B; };
struct V2 : virtual B { using B::B; };
struct D2 : V1, V2 {
using V1::V1;
using V2::V2;
};
D1 d1(0);
// ill-formed: ambiguous
D2 d2(0);
// OK: initializes virtual B base class, which initializes the A base class
// then initializes the V1 and V2 base classes as if by a defaulted default constructor
struct M { M(); M(int); };
struct N : M { using M::M; };
struct O : M {};
struct P : N, O { using N::N; using O::O; };
P p(0);
// OK: use M(0) to initialize N’s base class,
// use M() to initialize O’s base class
— end example ]
3
When an object is initialized by an inherited constructor, initialization of the object is complete when the
initialization of all subobjects is complete.
15.7
Construction and destruction
[class.cdtor]
1
For an object with a non-trivial constructor, referring to any non-static member or base class of the object
before the constructor begins execution results in undefined behavior. For an object with a non-trivial
destructor, referring to any non-static member or base class of the object after the destructor finishes execution
results in undefined behavior. [ Example:
struct X { int i; };
struct Y : X { Y(); };
// non-trivial
struct A { int a; };
struct B : public A { int j; Y y; };
// non-trivial
extern B bobj;
B* pb = &bobj;
// OK
int* p1 = &bobj.a;
// undefined, refers to base class member
int* p2 = &bobj.y.i;
// undefined, refers to member’s member
A* pa = &bobj;
// undefined, upcast to a base class type
B bobj;
// definition of bobj
extern X xobj;
int* p3 = &xobj.i;
// OK, X is a trivial class
X xobj;
For another example,
struct W { int j; };
§ 15.7
265
struct X : public virtual W { };
struct Y {
int* p;
X x;
Y() : p(&x.j) {
// undefined, x is not yet constructed
}
};
— end example ]
2
To explicitly or implicitly convert a pointer (a glvalue) referring to an object of class X to a pointer (reference)
to a direct or indirect base class B of X, the construction of X and the construction of all of its direct or
indirect bases that directly or indirectly derive from B shall have started and the destruction of these classes
shall not have completed, otherwise the conversion results in undefined behavior. To form a pointer to (or
access the value of) a direct non-static member of an object obj, the construction of obj shall have started
and its destruction shall not have completed, otherwise the computation of the pointer value (or accessing
the member value) results in undefined behavior. [ Example:
struct A { };
struct B : virtual A { };
struct C : B { };
struct D : virtual A { D(A*); };
struct X { X(A*); };
struct E : C, D, X {
E() : D(this),
// undefined: upcast from E* to A* might use path E* → D* → A*
// but D is not constructed
// “D((C*)this)” would be defined: E* → C* is defined because E() has started,
// and C* → A* is defined because C is fully constructed
X(this) {}
// defined: upon construction of X, C/B/D/A sublattice is fully constructed
};
— end example ]
3
Member functions, including virtual functions (13.3), can be called during construction or destruction (15.6.2).
When a virtual function is called directly or indirectly from a constructor or from a destructor, including
during the construction or destruction of the class’s non-static data members, and the object to which the
call applies is the object (call it x) under construction or destruction, the function called is the final overrider
in the constructor’s or destructor’s class and not one overriding it in a more-derived class. If the virtual
function call uses an explicit class member access (8.5.1.5) and the object expression refers to the complete
object of x or one of that object’s base class subobjects but not x or one of its base class subobjects, the
behavior is undefined. [ Example:
struct V {
virtual void f();
virtual void g();
};
struct A : virtual V {
virtual void f();
};
struct B : virtual V {
virtual void g();
B(V*, A*);
};
struct D : A, B {
virtual void f();
virtual void g();
D() : B((A*)this, this) { }
};
§ 15.7
266
B::B(V* v, A* a) {
f();
// calls V::f, not A::f
g();
// calls B::g, not D::g
v->g();
// v is base of B, the call is well-defined, calls B::g
a->f();
// undefined behavior, a’s type not a base of B
}
— end example ]
4
The typeid operator (8.5.1.8) can be used during construction or destruction (15.6.2). When typeid is
used in a constructor (including the mem-initializer or default member initializer (12.2) for a non-static
data member) or in a destructor, or used in a function called (directly or indirectly) from a constructor or
destructor, if the operand of typeid refers to the object under construction or destruction, typeid yields the
std::type_info object representing the constructor or destructor’s class. If the operand of typeid refers to
the object under construction or destruction and the static type of the operand is neither the constructor or
destructor’s class nor one of its bases, the behavior is undefined.
5
dynamic_casts (8.5.1.7) can be used during construction or destruction (15.6.2). When a dynamic_cast
is used in a constructor (including the mem-initializer or default member initializer for a non-static data
member) or in a destructor, or used in a function called (directly or indirectly) from a constructor or
destructor, if the operand of the dynamic_cast refers to the object under construction or destruction, this
object is considered to be a most derived object that has the type of the constructor or destructor’s class. If
the operand of the dynamic_cast refers to the object under construction or destruction and the static type
of the operand is not a pointer to or object of the constructor or destructor’s own class or one of its bases,
the dynamic_cast results in undefined behavior. [ Example:
struct V {
virtual void f();
};
struct A : virtual V { };
struct B : virtual V {
B(V*, A*);
};
struct D : A, B {
D() : B((A*)this, this) { }
};
B::B(V* v, A* a) {
typeid(*this);
// type_info for B
typeid(*v);
// well-defined: *v has type V, a base of B yields type_info for B
typeid(*a);
// undefined behavior: type A not a base of B
dynamic_cast<B*>(v);
// well-defined: v of type V*, V base of B results in B*
dynamic_cast<B*>(a);
// undefined behavior, a has type A*, A not a base of B
}
— end example ]
15.8
Copying and moving class objects
[class.copy]
1
A class object can be copied or moved in two ways: by initialization (15.1, 11.6), including for function
argument passing (8.5.1.2) and for function value return (9.6.3); and by assignment (8.5.18). Conceptually,
these two operations are implemented by a copy/move constructor (15.1) and copy/move assignment
operator (16.5.3).
2
A program is ill-formed if the copy/move constructor or the copy/move assignment operator for an object is
implicitly odr-used and the special member function is not accessible (Clause 14). [ Note: Copying/moving
one object into another using the copy/move constructor or the copy/move assignment operator does not
change the layout or size of either object.
— end note ]
15.8.1
Copy/move constructors
[class.copy.ctor]
1
A non-template constructor for class X is a copy constructor if its first parameter is of type X&, const X&,
volatile X& or const volatile X&, and either there are no other parameters or else all other parameters
§ 15.8.1
267
have default arguments (11.3.6). [ Example: X::X(const X&) and X::X(X&,int=1) are copy constructors.
struct X {
X(int);
X(const X&, int = 1);
};
X a(1);
// calls X(int);
X b(a, 0);
// calls X(const X&, int);
X c = b;
// calls X(const X&, int);
— end example ]
2
A non-template constructor for class X is a move constructor if its first parameter is of type X&&, const
X&&, volatile X&&, or const volatile X&&, and either there are no other parameters or else all other
parameters have default arguments (11.3.6). [ Example: Y::Y(Y&&) is a move constructor.
struct Y {
Y(const Y&);
Y(Y&&);
};
extern Y f(int);
Y d(f(1));
// calls Y(Y&&)
Y e = d;
// calls Y(const Y&)
— end example ]
3
[ Note: All forms of copy/move constructor may be declared for a class. [ Example:
struct X {
X(const X&);
X(X&);
// OK
X(X&&);
X(const X&&);
// OK, but possibly not sensible
};
— end example ]
— end note ]
4
[ Note: If a class X only has a copy constructor with a parameter of type X&, an initializer of type const X or
volatile X cannot initialize an object of type (possibly cv-qualified) X. [ Example:
struct X {
X();
// default constructor
X(X&);
// copy constructor with a non-const parameter
};
const X cx;
X x = cx;
// error: X::X(X&) cannot copy cx into x
— end example ]
— end note ]
5
A declaration of a constructor for a class X is ill-formed if its first parameter is of type (optionally cv-qualified)
X and either there are no other parameters or else all other parameters have default arguments. A member
function template is never instantiated to produce such a constructor signature. [ Example:
struct S {
template<typename T> S(T);
S();
};
S g;
void h() {
S a(g);
// does not instantiate the member template to produce S::S<S>(S);
// uses the implicitly declared copy constructor
}
— end example ]
6
If the class definition does not explicitly declare a copy constructor, a non-explicit one is declared implicitly.
If the class definition declares a move constructor or move assignment operator, the implicitly declared copy
constructor is defined as deleted; otherwise, it is defined as defaulted (11.4). The latter case is deprecated if
the class has a user-declared copy assignment operator or a user-declared destructor.
§ 15.8.1
268
7
The implicitly-declared copy constructor for a class X will have the form
X::X(const X&)
if each potentially constructed subobject of a class type M (or array thereof) has a copy constructor whose first
parameter is of type const M& or const volatile M&.120 Otherwise, the implicitly-declared copy constructor
will have the form
X::X(X&)
8
If the definition of a class X does not explicitly declare a move constructor, a non-explicit one will be implicitly
declared as defaulted if and only if
(8.1)
X does not have a user-declared copy constructor,
(8.2)
X does not have a user-declared copy assignment operator,
(8.3)
X does not have a user-declared move assignment operator, and
(8.4)
X does not have a user-declared destructor.
[ Note: When the move constructor is not implicitly declared or explicitly supplied, expressions that otherwise
would have invoked the move constructor may instead invoke a copy constructor.
— end note ]
9
The implicitly-declared move constructor for class X will have the form
X::X(X&&)
10
An implicitly-declared copy/move constructor is an inline public member of its class. A defaulted copy/move
constructor for a class X is defined as deleted (11.4.3) if X has:
(10.1)
a potentially constructed subobject type M (or array thereof) that cannot be copied/moved because
overload resolution (16.3), as applied to find M’s corresponding constructor, results in an ambiguity or a
function that is deleted or inaccessible from the defaulted constructor,
(10.2)
a variant member whose corresponding constructor as selected by overload resolution is non-trivial,
(10.3)
any potentially constructed subobject of a type with a destructor that is deleted or inaccessible from
the defaulted constructor, or,
(10.4)
for the copy constructor, a non-static data member of rvalue reference type.
A defaulted move constructor that is defined as deleted is ignored by overload resolution (16.3, 16.4). [ Note:
A deleted move constructor would otherwise interfere with initialization from an rvalue which can use the
copy constructor instead.
— end note ]
11
A copy/move constructor for class X is trivial if it is not user-provided and if:
(11.1)
class X has no virtual functions (13.3) and no virtual base classes (13.1), and
(11.2)
the constructor selected to copy/move each direct base class subobject is trivial, and
(11.3)
for each non-static data member of X that is of class type (or array thereof), the constructor selected to
copy/move that member is trivial;
otherwise the copy/move constructor is non-trivial.
12
A copy/move constructor that is defaulted and not defined as deleted is implicitly defined when it is odr-
used (6.2), when it is needed for constant evaluation (8.6), or when it is explicitly defaulted after its first
declaration. [Note: The copy/move constructor is implicitly defined even if the implementation elided its
odr-use (6.2, 15.2).
— end note ] If the implicitly-defined constructor would satisfy the requirements of a
constexpr constructor (10.1.5), the implicitly-defined constructor is constexpr.
13
Before the defaulted copy/move constructor for a class is implicitly defined, all non-user-provided copy/move
constructors for its potentially constructed subobjects shall have been implicitly defined.
[Note: An
implicitly-declared copy/move constructor has an implied exception specification (18.4).
— end note ]
14
The implicitly-defined copy/move constructor for a non-union class X performs a memberwise copy/move of
its bases and members. [ Note: Default member initializers of non-static data members are ignored. See also
the example in 15.6.2.
— end note ] The order of initialization is the same as the order of initialization of
bases and members in a user-defined constructor (see 15.6.2). Let x be either the parameter of the constructor
120) This implies that the reference parameter of the implicitly-declared copy constructor cannot bind to a volatile lvalue;
see C.1.9.
§ 15.8.1
269
or, for the move constructor, an xvalue referring to the parameter. Each base or non-static data member is
copied/moved in the manner appropriate to its type:
(14.1)
if the member is an array, each element is direct-initialized with the corresponding subobject of x;
(14.2)
if a member m has rvalue reference type T&&, it is direct-initialized with static_cast<T&&>(x.m);
(14.3)
otherwise, the base or member is direct-initialized with the corresponding base or member of x.
Virtual base class subobjects shall be initialized only once by the implicitly-defined copy/move constructor
(see 15.6.2).
15
The implicitly-defined copy/move constructor for a union X copies the object representation (6.7) of X.
15.8.2
Copy/move assignment operator
[class.copy.assign]
1
A user-declared copy assignment operator X::operator= is a non-static non-template member function of
class X with exactly one parameter of type X, X&, const X&, volatile X& or const volatile X&.121 [Note:
An overloaded assignment operator must be declared to have only one parameter; see 16.5.3.
— end note ]
[ Note: More than one form of copy assignment operator may be declared for a class.
— end note ] [ Note: If
a class X only has a copy assignment operator with a parameter of type X&, an expression of type const X
cannot be assigned to an object of type X. [ Example:
struct X {
X();
X& operator=(X&);
};
const X cx;
X x;
void f() {
x = cx;
// error: X::operator=(X&) cannot assign cx into x
}
— end example ]
— end note ]
2
If the class definition does not explicitly declare a copy assignment operator, one is declared implicitly.
If the class definition declares a move constructor or move assignment operator, the implicitly declared
copy assignment operator is defined as deleted; otherwise, it is defined as defaulted (11.4). The latter
case is deprecated if the class has a user-declared copy constructor or a user-declared destructor. The
implicitly-declared copy assignment operator for a class X will have the form
X& X::operator=(const X&)
if
(2.1)
each direct base class B of X has a copy assignment operator whose parameter is of type const B&,
const volatile B& or B, and
(2.2)
for all the non-static data members of X that are of a class type M (or array thereof), each such class
type has a copy assignment operator whose parameter is of type const M&, const volatile M& or M.122
Otherwise, the implicitly-declared copy assignment operator will have the form
X& X::operator=(X&)
3
A user-declared move assignment operator X::operator= is a non-static non-template member function of
class X with exactly one parameter of type X&&, const X&&, volatile X&&, or const volatile X&&. [ Note:
An overloaded assignment operator must be declared to have only one parameter; see 16.5.3.
— end note ]
[ Note: More than one form of move assignment operator may be declared for a class.
— end note ]
4
If the definition of a class X does not explicitly declare a move assignment operator, one will be implicitly
declared as defaulted if and only if
(4.1)
X does not have a user-declared copy constructor,
(4.2)
X does not have a user-declared move constructor,
121) Because a template assignment operator or an assignment operator taking an rvalue reference parameter is never a
copy assignment operator, the presence of such an assignment operator does not suppress the implicit declaration of a copy
assignment operator. Such assignment operators participate in overload resolution with other assignment operators, including
copy assignment operators, and, if selected, will be used to assign an object.
122) This implies that the reference parameter of the implicitly-declared copy assignment operator cannot bind to a volatile
lvalue; see C.1.9.
§ 15.8.2
270
(4.3)
X does not have a user-declared copy assignment operator, and
(4.4)
X does not have a user-declared destructor.
[ Example: The class definition
struct S {
int a;
S& operator=(const S&) = default;
};
will not have a default move assignment operator implicitly declared because the copy assignment operator
has been user-declared. The move assignment operator may be explicitly defaulted.
struct S {
int a;
S& operator=(const S&) = default;
S& operator=(S&&) = default;
};
— end example ]
5
The implicitly-declared move assignment operator for a class X will have the form
X& X::operator=(X&&);
6
The implicitly-declared copy/move assignment operator for class X has the return type X&; it returns the
object for which the assignment operator is invoked, that is, the object assigned to. An implicitly-declared
copy/move assignment operator is an inline public member of its class.
7
A defaulted copy/move assignment operator for class X is defined as deleted if X has:
(7.1)
a variant member with a non-trivial corresponding assignment operator and X is a union-like class, or
(7.2)
a non-static data member of const non-class type (or array thereof), or
(7.3)
a non-static data member of reference type, or
(7.4)
a direct non-static data member of class type M (or array thereof) or a direct base class M that cannot
be copied/moved because overload resolution (16.3), as applied to find M’s corresponding assignment
operator, results in an ambiguity or a function that is deleted or inaccessible from the defaulted
assignment operator.
A defaulted move assignment operator that is defined as deleted is ignored by overload resolution (16.3, 16.4).
8
Because a copy/move assignment operator is implicitly declared for a class if not declared by the user, a
base class copy/move assignment operator is always hidden by the corresponding assignment operator of a
derived class (16.5.3). A using-declaration (10.3.3) that brings in from a base class an assignment operator
with a parameter type that could be that of a copy/move assignment operator for the derived class is not
considered an explicit declaration of such an operator and does not suppress the implicit declaration of the
derived class operator; the operator introduced by the using-declaration is hidden by the implicitly-declared
operator in the derived class.
9
A copy/move assignment operator for class X is trivial if it is not user-provided and if:
(9.1)
class X has no virtual functions (13.3) and no virtual base classes (13.1), and
(9.2)
the assignment operator selected to copy/move each direct base class subobject is trivial, and
(9.3)
for each non-static data member of X that is of class type (or array thereof), the assignment operator
selected to copy/move that member is trivial;
otherwise the copy/move assignment operator is non-trivial.
10
A copy/move assignment operator for a class X that is defaulted and not defined as deleted is implicitly
defined when it is odr-used (6.2) (e.g., when it is selected by overload resolution to assign to an object of its
class type), when it is needed for constant evaluation (8.6), or when it is explicitly defaulted after its first
declaration. The implicitly-defined copy/move assignment operator is constexpr if
(10.1)
X is a literal type, and
(10.2)
the assignment operator selected to copy/move each direct base class subobject is a constexpr function,
and
§ 15.8.2
271
(10.3)
for each non-static data member of X that is of class type (or array thereof), the assignment operator
selected to copy/move that member is a constexpr function.
11
Before the defaulted copy/move assignment operator for a class is implicitly defined, all non-user-provided
copy/move assignment operators for its direct base classes and its non-static data members shall have been
implicitly defined. [ Note: An implicitly-declared copy/move assignment operator has an implied exception
specification (18.4).
— end note ]
12
The implicitly-defined copy/move assignment operator for a non-union class X performs memberwise copy-
/move assignment of its subobjects. The direct base classes of X are assigned first, in the order of their
declaration in the base-specifier-list, and then the immediate non-static data members of X are assigned, in
the order in which they were declared in the class definition. Let x be either the parameter of the function
or, for the move operator, an xvalue referring to the parameter. Each subobject is assigned in the manner
appropriate to its type:
(12.1)
if the subobject is of class type, as if by a call to operator= with the subobject as the object expression
and the corresponding subobject of x as a single function argument (as if by explicit qualification; that
is, ignoring any possible virtual overriding functions in more derived classes);
(12.2)
if the subobject is an array, each element is assigned, in the manner appropriate to the element type;
(12.3)
if the subobject is of scalar type, the built-in assignment operator is used.
It is unspecified whether subobjects representing virtual base classes are assigned more than once by the
implicitly-defined copy/move assignment operator. [ Example:
struct V { };
struct A : virtual V { };
struct B : virtual V { };
struct C : B, A { };
It is unspecified whether the virtual base class subobject V is assigned twice by the implicitly-defined
copy/move assignment operator for C. — end example ]
13
The implicitly-defined copy assignment operator for a union X copies the object representation (6.7) of X.
15.8.3
Copy/move elision
[class.copy.elision]
1
When certain criteria are met, an implementation is allowed to omit the copy/move construction of a class
object, even if the constructor selected for the copy/move operation and/or the destructor for the object
have side effects. In such cases, the implementation treats the source and target of the omitted copy/move
operation as simply two different ways of referring to the same object. If the first parameter of the selected
constructor is an rvalue reference to the object’s type, the destruction of that object occurs when the target
would have been destroyed; otherwise, the destruction occurs at the later of the times when the two objects
would have been destroyed without the optimization.123 This elision of copy/move operations, called copy
elision, is permitted in the following circumstances (which may be combined to eliminate multiple copies):
(1.1)
in a return statement in a function with a class return type, when the expression is the name of
a non-volatile automatic object (other than a function parameter or a variable introduced by the
exception-declaration of a handler (18.3)) with the same type (ignoring cv-qualification) as the function
return type, the copy/move operation can be omitted by constructing the automatic object directly
into the function call’s return object
(1.2)
in a throw-expression (8.5.17), when the operand is the name of a non-volatile automatic object
(other than a function or catch-clause parameter) whose scope does not extend beyond the end of
the innermost enclosing try-block (if there is one), the copy/move operation from the operand to the
exception object (18.1) can be omitted by constructing the automatic object directly into the exception
object
(1.3)
when the exception-declaration of an exception handler (Clause 18) declares an object of the same
type (except for cv-qualification) as the exception object (18.1), the copy operation can be omitted by
treating the exception-declaration as an alias for the exception object if the meaning of the program will
be unchanged except for the execution of constructors and destructors for the object declared by the
exception-declaration. [Note: There cannot be a move from the exception object because it is always
an lvalue.
— end note ]
123) Because only one object is destroyed instead of two, and one copy/move constructor is not executed, there is still one object
destroyed for each one constructed.
§ 15.8.3
272
Copy elision is required where an expression is evaluated in a context requiring a constant expression (8.6)
and in constant initialization (6.8.3.2). [ Note: Copy elision might not be performed if the same expression is
evaluated in another context.
— end note ]
2
[ Example:
class Thing {
public:
Thing();
~Thing();
Thing(const Thing&);
};
Thing f() {
Thing t;
return t;
}
Thing t2 = f();
struct A {
void *p;
constexpr A(): p(this) {}
};
constexpr A g() {
A a;
return a;
}
constexpr A a;
// well-formed, a.p points to a
constexpr A b = g();
// well-formed, b.p points to b
void g() {
A c = g();
// well-formed, c.p may point to c or to an ephemeral temporary
}
Here the criteria for elision can eliminate the copying of the local automatic object t into the result object
for the function call f(), which is the global object t2. Effectively, the construction of the local object t can
be viewed as directly initializing the global object t2, and that object’s destruction will occur at program
exit. Adding a move constructor to Thing has the same effect, but it is the move construction from the local
automatic object to t2 that is elided.
— end example ]
3
In the following copy-initialization contexts, a move operation might be used instead of a copy operation:
(3.1)
If the expression in a return statement (9.6.3) is a (possibly parenthesized) id-expression that names
an object with automatic storage duration declared in the body or parameter-declaration-clause of the
innermost enclosing function or lambda-expression, or
(3.2)
if the operand of a throw-expression (8.5.17) is the name of a non-volatile automatic object (other than
a function or catch-clause parameter) whose scope does not extend beyond the end of the innermost
enclosing try-block (if there is one),
overload resolution to select the constructor for the copy is first performed as if the object were designated
by an rvalue. If the first overload resolution fails or was not performed, or if the type of the first parameter
of the selected constructor is not an rvalue reference to the object’s type (possibly cv-qualified), overload
resolution is performed again, considering the object as an lvalue. [ Note: This two-stage overload resolution
must be performed regardless of whether copy elision will occur. It determines the constructor to be called if
elision is not performed, and the selected constructor must be accessible even if the call is elided.
— end
note ]
4
[ Example:
class Thing {
public:
Thing();
~Thing();
§ 15.8.3
273
Thing(Thing&&);
private:
Thing(const Thing&);
};
Thing f(bool b) {
Thing t;
if (b)
throw t;
// OK: Thing(Thing&&) used (or elided) to throw t
return t;
// OK: Thing(Thing&&) used (or elided) to return t
}
Thing t2 = f(false);
// OK: no extra copy/move performed, t2 constructed by call to f
struct Weird {
Weird();
Weird(Weird&);
};
Weird g() {
Weird w;
return w;
// OK: first overload resolution fails, second overload resolution selects Weird(Weird&)
}
— end example ]
15.9
Comparisons
[class.compare]
15.9.1
Defaulted comparison operator functions
[class.compare.default]
1
A defaulted comparison operator function (8.5.8, 8.5.9, 8.5.10) for some class C shall be a non-template
function declared in the member-specification of C that is
(1.1)
a non-static member of C having one parameter of type const C&, or
(1.2)
a friend of C having two parameters of type const C&.
15.9.2
Three-way comparison
[class.spaceship]
1
The direct base class subobjects of C, in the order of their declaration in the base-specifier-list of C, followed
by the non-static data members of C, in the order of their declaration in the member-specification of C,
form a list of subobjects. In that list, any subobject of array type is recursively expanded to the sequence
of its elements, in the order of increasing subscript. Let xi be an lvalue denoting the ith element in the
expanded list of subobjects for an object x (of length n), where xi is formed by a sequence of derived-to-base
conversions (16.3.3.1), class member access expressions (8.5.1.5), and array subscript expressions (8.5.1.1)
applied to x. The type of the expression xi <=> xi is denoted by Ri. It is unspecified whether virtual base
class subobjects are compared more than once.
2
If the declared return type of a defaulted three-way comparison operator function is auto, then the return
type is deduced as the common comparison type (see below) of R0, R1, · · · , Rn−1. [ Note: Otherwise, the
program will be ill-formed if the expression xi <=> xi is not implicitly convertible to the declared return type
for any i.
— end note ] If the return type is deduced as void, the operator function is defined as deleted.
3
The return value V of type R of the defaulted three-way comparison operator function with parameters
x and y of the same type is determined by comparing corresponding elements xi and yi in the expanded
lists of subobjects for x and y until the first index i where xi <=> yi yields a result value vi where vi
!= 0, contextually converted to bool, yields true; V is vi converted to R. If no such index exists, V is
std::strong_ordering::equal converted to R.
4
The common comparison type U of a possibly-empty list of n types T0, T1, · · · , Tn−1 is defined as follows:
(4.1)
If any Ti is not a comparison category type (21.10.2), U is void.
(4.2)
Otherwise, if at least one Ti is std::weak_equality, or at least one Ti is std::strong_equality and at
least one Tj is std::partial_ordering or std::weak_ordering, U is std::weak_equality (21.10.2.2).
(4.3)
Otherwise, if at least one Ti is std::strong_equality, U is std::strong_equality (21.10.2.3).
(4.4)
Otherwise, if at least one Ti is std::partial_ordering, U is std::partial_ordering (21.10.2.4).
§ 15.9.2
274
(4.5)
Otherwise, if at least one Ti is std::weak_ordering, U is std::weak_ordering (21.10.2.5).
(4.6)
Otherwise, U is std::strong_ordering (21.10.2.6). [ Note: In particular, this is the result when n is 0.
— end note ]
15.9.3
Other comparison operators
[class.rel.eq]
1
A defaulted relational (8.5.9) or equality (8.5.10) operator function for some operator @ shall have a declared
return type bool.
2
The operator function with parameters x and y is defined as deleted if
(2.1)
overload resolution (16.3), as applied to x <=> y (also considering synthesized candidates with reversed
order of parameters (16.3.1.2)), results in an ambiguity or a function that is deleted or inaccessible
from the operator function, or
(2.2)
the operator @ cannot be applied to the return type of x <=> y or y <=> x.
Otherwise, the operator function yields x <=> y @ 0 if an operator<=> with the original order of parameters
was selected, or 0 @ y <=> x otherwise.
3
[ Example:
struct C {
friend std::strong_equality operator<=>(const C&, const C&);
friend bool operator==(const C& x, const C& y) = default; // OK, returns x <=> y == 0
bool operator<(const C&) = default;
// OK, function is deleted
};
— end example ]
§ 15.9.3
275
16
Overloading
[over]
1
When two or more different declarations are specified for a single name in the same scope, that name is
said to be overloaded, and the declarations are called overloaded declarations. Only function and function
template declarations can be overloaded; variable and type declarations cannot be overloaded.
2
When an overloaded function name is used in a call, which overloaded function declaration is being referenced
is determined by comparing the types of the arguments at the point of use with the types of the parameters
in the overloaded declarations that are visible at the point of use. This function selection process is called
overload resolution and is defined in 16.3. [ Example:
double abs(double);
int abs(int);
abs(1);
// calls abs(int);
abs(1.0);
// calls abs(double);
— end example ]
16.1
Overloadable declarations
[over.load]
1
Not all function declarations can be overloaded. Those that cannot be overloaded are specified here. A
program is ill-formed if it contains two such non-overloadable declarations in the same scope. [Note: This
restriction applies to explicit declarations in a scope, and between such declarations and declarations made
through a using-declaration (10.3.3). It does not apply to sets of functions fabricated as a result of name
lookup (e.g., because of using-directives) or overload resolution (e.g., for operator functions).
— end note ]
2
Certain function declarations cannot be overloaded:
(2.1)
Function declarations that differ only in the return type, the exception specification (18.4), or both
cannot be overloaded.
(2.2)
Member function declarations with the same name and the same parameter-type-list (11.3.5) cannot be
overloaded if any of them is a static member function declaration (12.2.3). Likewise, member function
template declarations with the same name, the same parameter-type-list, and the same template
parameter lists cannot be overloaded if any of them is a static member function template declaration.
The types of the implicit object parameters constructed for the member functions for the purpose of
overload resolution (16.3.1) are not considered when comparing parameter-type-lists for enforcement
of this rule. In contrast, if there is no static member function declaration among a set of member
function declarations with the same name and the same parameter-type-list, then these member function
declarations can be overloaded if they differ in the type of their implicit object parameter. [ Example:
The following illustrates this distinction:
class X {
static void f();
void f();
// ill-formed
void f() const;
// ill-formed
void f() const volatile;
// ill-formed
void g();
void g() const;
// OK: no static g
void g() const volatile;
// OK: no static g
};
— end example ]
(2.3)
Member function declarations with the same name and the same parameter-type-list (11.3.5) as well as
member function template declarations with the same name, the same parameter-type-list, and the same
template parameter lists cannot be overloaded if any of them, but not all, have a ref-qualifier (11.3.5).
[ Example:
class Y {
void h() &;
void h() const &;
// OK
void h() &&;
// OK, all declarations have a ref-qualifier
§
16.1
276
void i() &;
void i() const;
// ill-formed, prior declaration of i
// has a ref-qualifier
};
— end example ]
3
[ Note: As specified in 11.3.5, function declarations that have equivalent parameter declarations and requires-
clauses, if any (17.4.2), declare the same function and therefore cannot be overloaded:
(3.1)
Parameter declarations that differ only in the use of equivalent typedef “types” are equivalent. A
typedef is not a separate type, but only a synonym for another type (10.1.3). [ Example:
typedef int Int;
void f(int i);
void f(Int i);
// OK: redeclaration of f(int)
void f(int i) { /* ... */ }
void f(Int i) { /* ... */ }
// error: redefinition of f(int)
— end example ]
Enumerations, on the other hand, are distinct types and can be used to distinguish overloaded function
declarations. [ Example:
enum E { a };
void f(int i) { /* ... */ }
void f(E i)
{ /* ... */ }
— end example ]
(3.2)
Parameter declarations that differ only in a pointer * versus an array [] are equivalent. That is, the
array declaration is adjusted to become a pointer declaration (11.3.5). Only the second and subsequent
array dimensions are significant in parameter types (11.3.4). [ Example:
int f(char*);
int f(char[]);
// same as f(char*);
int f(char[7]);
// same as f(char*);
int f(char[9]);
// same as f(char*);
int g(char(*)[10]);
int g(char[5][10]);
// same as g(char(*)[10]);
int g(char[7][10]);
// same as g(char(*)[10]);
int g(char(*)[20]);
// different from g(char(*)[10]);
— end example ]
(3.3)
Parameter declarations that differ only in that one is a function type and the other is a pointer to
the same function type are equivalent. That is, the function type is adjusted to become a pointer to
function type (11.3.5). [ Example:
void h(int());
void h(int (*)());
// redeclaration of h(int())
void h(int x()) { }
// definition of h(int())
void h(int (*x)()) { }
// ill-formed: redefinition of h(int())
— end example ]
(3.4)
Parameter declarations that differ only in the presence or absence of const and/or volatile are
equivalent. That is, the const and volatile type-specifiers for each parameter type are ignored when
determining which function is being declared, defined, or called. [ Example:
typedef const int cInt;
int f (int);
int f (const int);
// redeclaration of f(int)
int f (int) { /* ... */ }
// definition of f(int)
int f (cInt) { /* ... */ }
// error: redefinition of f(int)
— end example ]
§ 16.1
277
Only the const and volatile type-specifiers at the outermost level of the parameter type specification
are ignored in this fashion; const and volatile type-specifiers buried within a parameter type
specification are significant and can be used to distinguish overloaded function declarations.124
In
particular, for any type T, “pointer to T”, “pointer to const T”, and “pointer to volatile T” are
considered distinct parameter types, as are “reference to T”, “reference to const T”, and “reference to
volatile T”.
(3.5)
Two parameter declarations that differ only in their default arguments are equivalent.
[Example:
Consider the following:
void f (int i, int j);
void f (int i, int j = 99);
// OK: redeclaration of f(int, int)
void f (int i = 88, int j);
// OK: redeclaration of f(int, int)
void f ();
// OK: overloaded declaration of f
void prog () {
f (1, 2);
// OK: call f(int, int)
f (1);
// OK: call f(int, int)
f ();
// error: f(int, int) or f()?
}
— end example ]
— end note ]
16.2
Declaration matching
[over.dcl]
1
Two function declarations of the same name refer to the same function if they are in the same scope and
have equivalent parameter declarations (16.1) and equivalent trailing requires-clauses, if any (Clause 11). A
function member of a derived class is not in the same scope as a function member of the same name in a
base class. [ Example:
struct B {
int f(int);
};
struct D : B {
int f(const char*);
};
Here D::f(const char*) hides B::f(int) rather than overloading it.
void h(D* pd) {
pd->f(1);
// error:
// D::f(const char*) hides B::f(int)
pd->B::f(1);
// OK
pd->f("Ben");
// OK, calls D::f
}
— end example ]
2
A locally declared function is not in the same scope as a function in a containing scope. [ Example:
void f(const char*);
void g() {
extern void f(int);
f("asdf");
// error: f(int) hides f(const char*)
// so there is no f(const char*) in this scope
}
void caller () {
extern void callee(int, int);
{
extern void callee(int);
// hides callee(int, int)
callee(88, 99);
// error: only callee(int) in scope
124) When a parameter type includes a function type, such as in the case of a parameter type that is a pointer to function, the
const and volatile type-specifiers at the outermost level of the parameter type specifications for the inner function type are
also ignored.
§ 16.2
278
}
}
— end example ]
3
Different versions of an overloaded member function can be given different access rules. [ Example:
class buffer {
private:
char* p;
int size;
protected:
buffer(int s, char* store) { size = s; p = store; }
public:
buffer(int s) { p = new char[size = s]; }
};
— end example ]
16.3
Overload resolution
[over.match]
1
Overload resolution is a mechanism for selecting the best function to call given a list of expressions that are
to be the arguments of the call and a set of candidate functions that can be called based on the context of
the call. The selection criteria for the best function are the number of arguments, how well the arguments
match the parameter-type-list of the candidate function, how well (for non-static member functions) the
object matches the implicit object parameter, and certain other properties of the candidate function. [ Note:
The function selected by overload resolution is not guaranteed to be appropriate for the context. Other
restrictions, such as the accessibility of the function, can make its use in the calling context ill-formed.
— end
note ]
2
Overload resolution selects the function to call in seven distinct contexts within the language:
(2.1)
invocation of a function named in the function call syntax (16.3.1.1.1);
(2.2)
invocation of a function call operator, a pointer-to-function conversion function, a reference-to-pointer-
to-function conversion function, or a reference-to-function conversion function on a class object named
in the function call syntax (16.3.1.1.2);
(2.3)
invocation of the operator referenced in an expression (16.3.1.2);
(2.4)
invocation of a constructor for default- or direct-initialization (11.6) of a class object (16.3.1.3);
(2.5)
invocation of a user-defined conversion for copy-initialization (11.6) of a class object (16.3.1.4);
(2.6)
invocation of a conversion function for initialization of an object of a non-class type from an expression
of class type (16.3.1.5); and
(2.7)
invocation of a conversion function for conversion to a glvalue or class prvalue to which a reference (11.6.3)
will be directly bound (16.3.1.6).
Each of these contexts defines the set of candidate functions and the list of arguments in its own unique way.
But, once the candidate functions and argument lists have been identified, the selection of the best function
is the same in all cases:
(2.8)
First, a subset of the candidate functions (those that have the proper number of arguments and meet
certain other conditions) is selected to form a set of viable functions (16.3.2).
(2.9)
Then the best viable function is selected based on the implicit conversion sequences (16.3.3.1) needed
to match each argument to the corresponding parameter of each viable function.
3
If a best viable function exists and is unique, overload resolution succeeds and produces it as the result.
Otherwise overload resolution fails and the invocation is ill-formed. When overload resolution succeeds,
and the best viable function is not accessible (Clause 14) in the context in which it is used, the program is
ill-formed.
16.3.1
Candidate functions and argument lists
[over.match.funcs]
1
The subclauses of 16.3.1 describe the set of candidate functions and the argument list submitted to overload
resolution in each context in which overload resolution is used. The source transformations and constructions
defined in these subclauses are only for the purpose of describing the overload resolution process. An
implementation is not required to use such transformations and constructions.
§ 16.3.1
279
2
The set of candidate functions can contain both member and non-member functions to be resolved against
the same argument list. So that argument and parameter lists are comparable within this heterogeneous
set, a member function is considered to have an extra parameter, called the implicit object parameter, which
represents the object for which the member function has been called. For the purposes of overload resolution,
both static and non-static member functions have an implicit object parameter, but constructors do not.
3
Similarly, when appropriate, the context can construct an argument list that contains an implied object
argument to denote the object to be operated on. Since arguments and parameters are associated by position
within their respective lists, the convention is that the implicit object parameter, if present, is always the
first parameter and the implied object argument, if present, is always the first argument.
4
For non-static member functions, the type of the implicit object parameter is
(4.1)
“lvalue reference to cv X” for functions declared without a ref-qualifier or with the & ref-qualifier
(4.2)
“rvalue reference to cv X” for functions declared with the && ref-qualifier
where X is the class of which the function is a member and cv is the cv-qualification on the member function
declaration. [ Example: For a const member function of class X, the extra parameter is assumed to have
type “reference to const X”. — end example ] For conversion functions, the function is considered to be
a member of the class of the implied object argument for the purpose of defining the type of the implicit
object parameter. For non-conversion functions introduced by a using-declaration into a derived class, the
function is considered to be a member of the derived class for the purpose of defining the type of the implicit
object parameter. For static member functions, the implicit object parameter is considered to match any
object (since if the function is selected, the object is discarded). [Note: No actual type is established for
the implicit object parameter of a static member function, and no attempt will be made to determine a
conversion sequence for that parameter (16.3.3).
— end note ]
5
During overload resolution, the implied object argument is indistinguishable from other arguments. The
implicit object parameter, however, retains its identity since no user-defined conversions can be applied to
achieve a type match with it. For non-static member functions declared without a ref-qualifier, an additional
rule applies:
(5.1)
even if the implicit object parameter is not const-qualified, an rvalue can be bound to the parameter as
long as in all other respects the argument can be converted to the type of the implicit object parameter.
[ Note: The fact that such an argument is an rvalue does not affect the ranking of implicit conversion
sequences (16.3.3.2).
— end note ]
6
Because other than in list-initialization only one user-defined conversion is allowed in an implicit conversion
sequence, special rules apply when selecting the best user-defined conversion (16.3.3, 16.3.3.1). [ Example:
class T {
public:
T();
};
class C : T {
public:
C(int);
};
T a = 1;
// ill-formed: T(C(1)) not tried
— end example ]
7
In each case where a candidate is a function template, candidate function template specializations are
generated using template argument deduction (17.9.3, 17.9.2). Those candidates are then handled as
candidate functions in the usual way.125 A given name can refer to one or more function templates and also
to a set of overloaded non-template functions. In such a case, the candidate functions generated from each
function template are combined with the set of non-template candidate functions.
8
A defaulted move special function (15.8) that is defined as deleted is excluded from the set of candidate
functions in all contexts.
125) The process of argument deduction fully determines the parameter types of the function template specializations, i.e.,
the parameters of function template specializations contain no template parameter types. Therefore, except where specified
otherwise, function template specializations and non-template functions (11.3.5) are treated equivalently for the remainder of
overload resolution.
§ 16.3.1
280
16.3.1.1
Function call syntax
[over.match.call]
1
In a function call (8.5.1.2)
postfix-expression ( expression-listopt )
if the postfix-expression denotes a set of overloaded functions and/or function templates, overload resolution is
applied as specified in 16.3.1.1.1. If the postfix-expression denotes an object of class type, overload resolution
is applied as specified in 16.3.1.1.2.
2
If the postfix-expression denotes the address of a set of overloaded functions and/or function templates,
overload resolution is applied using that set as described above. If the function selected by overload resolution
is a non-static member function, the program is ill-formed.
[Note: The resolution of the address of an
overload set in other contexts is described in 16.4.
— end note ]
16.3.1.1.1
Call to named function
[over.call.func]
1
Of interest in 16.3.1.1.1 are only those function calls in which the postfix-expression ultimately contains a
name that denotes one or more functions that might be called. Such a postfix-expression, perhaps nested
arbitrarily deep in parentheses, has one of the following forms:
postfix-expression:
postfix-expression . id-expression
postfix-expression -> id-expression
primary-expression
These represent two syntactic subcategories of function calls: qualified function calls and unqualified function
calls.
2
In qualified function calls, the name to be resolved is an id-expression and is preceded by an -> or . operator.
Since the construct A->B is generally equivalent to (*A).B, the rest of Clause 16 assumes, without loss of
generality, that all member function calls have been normalized to the form that uses an object and the
. operator. Furthermore, Clause 16 assumes that the postfix-expression that is the left operand of the .
operator has type “cv T” where T denotes a class.126 Under this assumption, the id-expression in the call
is looked up as a member function of T following the rules for looking up names in classes (13.2). The
function declarations found by that lookup constitute the set of candidate functions. The argument list is the
expression-list in the call augmented by the addition of the left operand of the . operator in the normalized
member function call as the implied object argument (16.3.1).
3
In unqualified function calls, the name is not qualified by an -> or . operator and has the more general form
of a primary-expression. The name is looked up in the context of the function call following the normal
rules for name lookup in function calls (6.4). The function declarations found by that lookup constitute the
set of candidate functions. Because of the rules for name lookup, the set of candidate functions consists
(1) entirely of non-member functions or (2) entirely of member functions of some class T. In case (1), the
argument list is the same as the expression-list in the call. In case (2), the argument list is the expression-list
in the call augmented by the addition of an implied object argument as in a qualified function call. If the
keyword this (12.2.2.1) is in scope and refers to class T, or a derived class of T, then the implied object
argument is (*this). If the keyword this is not in scope or refers to another class, then a contrived object
of type T becomes the implied object argument.127 If the argument list is augmented by a contrived object
and overload resolution selects one of the non-static member functions of T, the call is ill-formed.
16.3.1.1.2
Call to object of class type
[over.call.object]
1
If the postfix-expression E in the function call syntax evaluates to a class object of type “cv T”, then the set
of candidate functions includes at least the function call operators of T. The function call operators of T are
obtained by ordinary lookup of the name operator() in the context of (E).operator().
2
In addition, for each non-explicit conversion function declared in T of the form
operator conversion-type-id ( ) cv-qualifier ref-qualifieropt noexcept-specifieropt attribute-specifier-seqopt ;
where cv-qualifier is the same cv-qualification as, or a greater cv-qualification than, cv, and where conversion-
type-id denotes the type “pointer to function of (P1,...,Pn) returning R”, or the type “reference to pointer
126) Note that cv-qualifiers on the type of objects are significant in overload resolution for both glvalue and class prvalue objects.
127) An implied object argument must be contrived to correspond to the implicit object parameter attributed to member
functions during overload resolution. It is not used in the call to the selected function. Since the member functions all have the
same implicit object parameter, the contrived object will not be the cause to select or reject a function.
§ 16.3.1.1.2
281
to function of (P1,...,Pn) returning R”, or the type “reference to function of (P1,...,Pn) returning R”, a
surrogate call function with the unique name call-function and having the form
R call-function ( conversion-type-id F, P1
a1, . . . , Pn an) { return F (a1, . . . , an); }
is also considered as a candidate function. Similarly, surrogate call functions are added to the set of candidate
functions for each non-explicit conversion function declared in a base class of T provided the function is not
hidden within T by another intervening declaration.128
3
If such a surrogate call function is selected by overload resolution, the corresponding conversion function will
be called to convert E to the appropriate function pointer or reference, and the function will then be invoked
with the arguments of the call. If the conversion function cannot be called (e.g., because of an ambiguity),
the program is ill-formed.
4
The argument list submitted to overload resolution consists of the argument expressions present in the
function call syntax preceded by the implied object argument (E). [ Note: When comparing the call against
the function call operators, the implied object argument is compared against the implicit object parameter of
the function call operator. When comparing the call against a surrogate call function, the implied object
argument is compared against the first parameter of the surrogate call function. The conversion function
from which the surrogate call function was derived will be used in the conversion sequence for that parameter
since it converts the implied object argument to the appropriate function pointer or reference required by
that first parameter.
— end note ] [ Example:
int f1(int);
int f2(float);
typedef int (*fp1)(int);
typedef int (*fp2)(float);
struct A {
operator fp1() { return f1; }
operator fp2() { return f2; }
} a;
int i = a(1);
// calls f1 via pointer returned from conversion function
— end example ]
16.3.1.2
Operators in expressions
[over.match.oper]
1
If no operand of an operator in an expression has a type that is a class or an enumeration, the operator is
assumed to be a built-in operator and interpreted according to 8.5. [ Note: Because ., .*, and :: cannot
be overloaded, these operators are always built-in operators interpreted according to 8.5.
?: cannot be
overloaded, but the rules in this subclause are used to determine the conversions to be applied to the second
and third operands when they have class or enumeration type (8.5.16).
— end note ] [ Example:
struct String {
String (const String&);
String (const char*);
operator const char* ();
};
String operator + (const String&, const String&);
void f() {
const char* p= "one" + "two";
// ill-formed because neither operand has class or enumeration type
int I = 1 + 1;
// always evaluates to 2 even if class or enumeration types exist
// that would perform the operation.
}
— end example ]
2
If either operand has a type that is a class or an enumeration, a user-defined operator function might be
declared that implements this operator or a user-defined conversion can be necessary to convert the operand to
a type that is appropriate for a built-in operator. In this case, overload resolution is used to determine which
operator function or built-in operator is to be invoked to implement the operator. Therefore, the operator
notation is first transformed to the equivalent function-call notation as summarized in Table 12 (where @
128) Note that this construction can yield candidate call functions that cannot be differentiated one from the other by overload
resolution because they have identical declarations or differ only in their return type. The call will be ambiguous if overload
resolution cannot select a match to the call that is uniquely better than such undifferentiable functions.
§ 16.3.1.2
282
denotes one of the operators covered in the specified subclause). However, the operands are sequenced in the
order prescribed for the built-in operator (8.5).
Table 12 — Relationship between operator and function call notation
Subclause
Expression
As member function
As non-member function
16.5.1
@a
(a).operator@ ( )
operator@(a)
16.5.2
a@b
(a).operator@ (b)
operator@(a, b)
16.5.3
a=b
(a).operator= (b)
16.5.5
a[b]
(a).operator[](b)
16.5.6
a->
(a).operator->( )
16.5.7
a@
(a).operator@ (0)
operator@(a, 0)
3
For a unary operator @ with an operand of a type whose cv-unqualified version is T1, and for a binary operator
@ with a left operand of a type whose cv-unqualified version is T1 and a right operand of a type whose
cv-unqualified version is T2, three sets of candidate functions, designated member candidates, non-member
candidates and built-in candidates, are constructed as follows:
(3.1)
If T1 is a complete class type or a class currently being defined, the set of member candidates is the
result of the qualified lookup of T1::operator@ (16.3.1.1.1); otherwise, the set of member candidates
is empty.
(3.2)
The set of non-member candidates is the result of the unqualified lookup of operator@ in the context of
the expression according to the usual rules for name lookup in unqualified function calls (6.4.2) except
that all member functions are ignored. However, if no operand has a class type, only those non-member
functions in the lookup set that have a first parameter of type T1 or “reference to cv T1”, when T1 is
an enumeration type, or (if there is a right operand) a second parameter of type T2 or “reference to
cv T2”, when T2 is an enumeration type, are candidate functions.
(3.3)
For the operator ,, the unary operator &, or the operator ->, the built-in candidates set is empty.
For all other operators, the built-in candidates include all of the candidate operator functions defined
in 16.6 that, compared to the given operator,
(3.3.1)
have the same operator name, and
(3.3.2)
accept the same number of operands, and
(3.3.3)
accept operand types to which the given operand or operands can be converted according to
16.3.3.1, and
(3.3.4)
do not have the same parameter-type-list as any non-member candidate that is not a function
template specialization.
4
For the built-in assignment operators, conversions of the left operand are restricted as follows:
(4.1)
no temporaries are introduced to hold the left operand, and
(4.2)
no user-defined conversions are applied to the left operand to achieve a type match with the left-most
parameter of a built-in candidate.
5
For all other operators, no such restrictions apply.
6
The set of candidate functions for overload resolution for some operator @ is the union of the member
candidates, the non-member candidates, and the built-in candidates for that operator @. If that operator is a
relational (8.5.9) or equality (8.5.10) operator with operands x and y, then for each member, non-member, or
built-in candidate for the operator <=>:
(6.1)
that operator is added to the set of candidate functions for overload resolution if x <=> y @ 0 is
well-formed using that operator<=>; and
(6.2)
a synthesized candidate is added to the candidate set where the order of the two parameters is reversed
if
0 @ y <=> x is well-formed using that operator<=>;
where in each case operator<=> candidates are not considered for the recursive lookup of operator @.
7
The argument list contains all of the operands of the operator. The best function from the set of candidate
functions is selected according to 16.3.2 and 16.3.3.129 [ Example:
129) If the set of candidate functions is empty, overload resolution is unsuccessful.
§ 16.3.1.2
283
struct A {
operator int();
};
A operator+(const A&, const A&);
void m() {
A a, b;
a + b;
// operator+(a, b) chosen over int(a) + int(b)
}
— end example ]
8
If an operator<=> candidate is selected by overload resolution for an operator @, but @ is not <=>, x @ y
is interpreted as 0 @ y <=> x if the selected candidate is a synthesized candidate with reversed order of
parameters, or x <=> y @ 0 otherwise, using the selected operator<=> candidate.
9
If a built-in candidate is selected by overload resolution, the operands of class type are converted to the
types of the corresponding parameters of the selected operation function, except that the second standard
conversion sequence of a user-defined conversion sequence (16.3.3.1.2) is not applied. Then the operator is
treated as the corresponding built-in operator and interpreted according to 8.5. [ Example:
struct X {
operator double();
};
struct Y {
operator int*();
};
int *a = Y() + 100.0;
// error: pointer arithmetic requires integral operand
int *b = Y() + X();
// error: pointer arithmetic requires integral operand
— end example ]
10
The second operand of operator -> is ignored in selecting an operator-> function, and is not an argument
when the operator-> function is called. When operator-> returns, the operator -> is applied to the value
returned, with the original second operand.130
11
If the operator is the operator ,, the unary operator &, or the operator ->, and there are no viable functions,
then the operator is assumed to be the built-in operator and interpreted according to 8.5.
12
[ Note: The lookup rules for operators in expressions are different than the lookup rules for operator function
names in a function call, as shown in the following example:
struct A { };
void operator + (A, A);
struct B {
void operator + (B);
void f ();
};
A a;
void B::f() {
operator+ (a,a);
// error: global operator hidden by member
a + a;
// OK: calls global operator+
}
— end note ]
16.3.1.3
Initialization by constructor
[over.match.ctor]
1
When objects of class type are direct-initialized (11.6), copy-initialized from an expression of the same or
a derived class type (11.6), or default-initialized (11.6), overload resolution selects the constructor. For
direct-initialization or default-initialization that is not in the context of copy-initialization, the candidate
functions are all the constructors of the class of the object being initialized. For copy-initialization, the
130) If the value returned by the operator-> function has class type, this may result in selecting and calling another operator->
function. The process repeats until an operator-> function returns a value of non-class type.
§ 16.3.1.3
284
candidate functions are all the converting constructors (15.3.1) of that class. The argument list is the
expression-list or assignment-expression of the initializer.
16.3.1.4
Copy-initialization of class by user-defined conversion
[over.match.copy]
1
Under the conditions specified in 11.6, as part of a copy-initialization of an object of class type, a user-defined
conversion can be invoked to convert an initializer expression to the type of the object being initialized.
Overload resolution is used to select the user-defined conversion to be invoked.
[Note: The conversion
performed for indirect binding to a reference to a possibly cv-qualified class type is determined in terms of
a corresponding non-reference copy-initialization.
— end note ] Assuming that “cv1 T” is the type of the
object being initialized, with T a class type, the candidate functions are selected as follows:
(1.1)
The converting constructors (15.3.1) of T are candidate functions.
(1.2)
When the type of the initializer expression is a class type “cv S”, the non-explicit conversion functions
of S and its base classes are considered. When initializing a temporary object (12.2) to be bound to
the first parameter of a constructor where the parameter is of type “reference to possibly cv-qualified
T” and the constructor is called with a single argument in the context of direct-initialization of an
object of type “cv2 T”, explicit conversion functions are also considered. Those that are not hidden
within S and yield a type whose cv-unqualified version is the same type as T or is a derived class thereof
are candidate functions. Conversion functions that return “reference to X” return lvalues or xvalues,
depending on the type of reference, of type X and are therefore considered to yield X for this process of
selecting candidate functions.
2
In both cases, the argument list has one argument, which is the initializer expression. [ Note: This argument
will be compared against the first parameter of the constructors and against the implicit object parameter of
the conversion functions.
— end note ]
16.3.1.5
Initialization by conversion function
[over.match.conv]
1
Under the conditions specified in 11.6, as part of an initialization of an object of non-class type, a conversion
function can be invoked to convert an initializer expression of class type to the type of the object being
initialized. Overload resolution is used to select the conversion function to be invoked. Assuming that “cv1
T” is the type of the object being initialized, and “cv S” is the type of the initializer expression, with S a
class type, the candidate functions are selected as follows:
(1.1)
The conversion functions of S and its base classes are considered. Those non-explicit conversion
functions that are not hidden within S and yield type T or a type that can be converted to type T via
a standard conversion sequence (16.3.3.1.1) are candidate functions. For direct-initialization, those
explicit conversion functions that are not hidden within S and yield type T or a type that can be
converted to type T with a qualification conversion (7.5) are also candidate functions. Conversion
functions that return a cv-qualified type are considered to yield the cv-unqualified version of that type
for this process of selecting candidate functions. Conversion functions that return “reference to cv2
X” return lvalues or xvalues, depending on the type of reference, of type “cv2 X” and are therefore
considered to yield X for this process of selecting candidate functions.
2
The argument list has one argument, which is the initializer expression.
[Note: This argument will be
compared against the implicit object parameter of the conversion functions.
— end note ]
16.3.1.6
Initialization by conversion function for direct reference binding
[over.match.ref]
1
Under the conditions specified in 11.6.3, a reference can be bound directly to a glvalue or class prvalue that is
the result of applying a conversion function to an initializer expression. Overload resolution is used to select
the conversion function to be invoked. Assuming that “reference to cv1 T” is the type of the reference being
initialized, and “cv S” is the type of the initializer expression, with S a class type, the candidate functions
are selected as follows:
(1.1)
The conversion functions of S and its base classes are considered. Those non-explicit conversion functions
that are not hidden within S and yield type “lvalue reference to cv2 T2” (when initializing an lvalue
reference or an rvalue reference to function) or “cv2 T2” or “rvalue reference to cv2 T2” (when initializing
an rvalue reference or an lvalue reference to function), where “cv1 T” is reference-compatible (11.6.3)
with “cv2 T2”, are candidate functions. For direct-initialization, those explicit conversion functions that
are not hidden within S and yield type “lvalue reference to cv2 T2” or “cv2 T2” or “rvalue reference to
cv2 T2”, respectively, where T2 is the same type as T or can be converted to type T with a qualification
conversion (7.5), are also candidate functions.
§ 16.3.1.6
285
2
The argument list has one argument, which is the initializer expression.
[Note: This argument will be
compared against the implicit object parameter of the conversion functions.
— end note ]
16.3.1.7
Initialization by list-initialization
[over.match.list]
1
When objects of non-aggregate class type T are list-initialized such that 11.6.4 specifies that overload resolution
is performed according to the rules in this subclause, overload resolution selects the constructor in two phases:
(1.1)
Initially, the candidate functions are the initializer-list constructors (11.6.4) of the class T and the
argument list consists of the initializer list as a single argument.
(1.2)
If no viable initializer-list constructor is found, overload resolution is performed again, where the
candidate functions are all the constructors of the class T and the argument list consists of the elements
of the initializer list.
If the initializer list has no elements and T has a default constructor, the first phase is omitted. In copy-list-
initialization, if an explicit constructor is chosen, the initialization is ill-formed. [ Note: This differs from
other situations (16.3.1.3, 16.3.1.4), where only converting constructors are considered for copy-initialization.
This restriction only applies if this initialization is part of the final result of overload resolution.
— end note ]
16.3.1.8
Class template argument deduction
[over.match.class.deduct]
1
When resolving a placeholder for a deduced class type (10.1.7.5) where the template-name names a primary
class template C, a set of functions and function templates is formed comprising:
(1.1)
If C is defined, for each constructor of C, a function template with the following properties:
(1.1.1)
The template parameters are the template parameters of C followed by the template parameters
(including default template arguments) of the constructor, if any.
(1.1.2)
The types of the function parameters are those of the constructor.
(1.1.3)
The return type is the class template specialization designated by C and template arguments
corresponding to the template parameters of C.
(1.2)
If C is not defined or does not declare any constructors, an additional function template derived as
above from a hypothetical constructor C().
(1.3)
An additional function template derived as above from a hypothetical constructor C(C), called the copy
deduction candidate.
(1.4)
For each deduction-guide, a function or function template with the following properties:
(1.4.1)
The template parameters, if any, and function parameters are those of the deduction-guide.
(1.4.2)
The return type is the simple-template-id of the deduction-guide.
2
Initialization and overload resolution are performed as described in 11.6 and 16.3.1.3, 16.3.1.4, or 16.3.1.7 (as
appropriate for the type of initialization performed) for an object of a hypothetical class type, where the
selected functions and function templates are considered to be the constructors of that class type for the
purpose of forming an overload set, and the initializer is provided by the context in which class template
argument deduction was performed. As an exception, the first phase in 16.3.1.7 (considering initializer-list
constructors) is omitted if the initializer list consists of a single expression of type cv U, where U is a
specialization of C or a class derived from a specialization of C. Each such notional constructor is considered to
be explicit if the function or function template was generated from a constructor or deduction-guide that was
declared explicit. All such notional constructors are considered to be public members of the hypothetical
class type.
3
[ Example:
template <class T> struct A {
explicit A(const T&, ...) noexcept;
// #1
A(T&&, ...);
// #2
};
int i;
A a1 = { i, i };
// error: explicit constructor #1 selected in copy-list-initialization during deduction,
// cannot deduce from non-forwarding rvalue reference in #2
A a2{i, i};
// OK, #1 deduces to A<int> and also initializes
A a3{0, i};
// OK, #2 deduces to A<int> and also initializes
§ 16.3.1.8
286
A a4 = {0, i};
// OK, #2 deduces to A<int> and also initializes
template <class T> A(const T&, const T&) -> A<T&>;
// #3
template <class T> explicit A(T&&, T&&) -> A<T>;
// #4
A a5 = {0, 1};
// error: explicit deduction guide #4 selected in copy-list-initialization during deduction
A a6{0,1};
// OK, #4 deduces to A<int> and #2 initializes
A a7 = {0, i};
// error: #3 deduces to A<int&>, #1 and #2 declare same constructor
A a8{0,i};
// error: #3 deduces to A<int&>, #1 and #2 declare same constructor
template <class T> struct B {
template <class U> using TA = T;
template <class U> B(U, TA<U>);
};
B b{(int*)0, (char*)0};
// OK, deduces B<char*>
— end example ]
16.3.2
Viable functions
[over.match.viable]
1
From the set of candidate functions constructed for a given context (16.3.1), a set of viable functions is chosen,
from which the best function will be selected by comparing argument conversion sequences and associated
constraints (17.4.2) for the best fit (16.3.3). The selection of viable functions considers associated constraints,
if any, and relationships between arguments and function parameters other than the ranking of conversion
sequences.
2
First, to be a viable function, a candidate function shall have enough parameters to agree in number with
the arguments in the list.
(2.1)
If there are m arguments in the list, all candidate functions having exactly m parameters are viable.
(2.2)
A candidate function having fewer than m parameters is viable only if it has an ellipsis in its parameter
list (11.3.5). For the purposes of overload resolution, any argument for which there is no corresponding
parameter is considered to “match the ellipsis” (16.3.3.1.3) .
(2.3)
A candidate function having more than m parameters is viable only if the (m+1)-st parameter has a
default argument (11.3.6).131 For the purposes of overload resolution, the parameter list is truncated
on the right, so that there are exactly m parameters.
3
Second, for a function to be viable, if it has associated constraints, those constraints shall be satisfied (17.4.2).
4
Third, for F to be a viable function, there shall exist for each argument an implicit conversion sequence (16.3.3.1)
that converts that argument to the corresponding parameter of F. If the parameter has reference type, the
implicit conversion sequence includes the operation of binding the reference, and the fact that an lvalue
reference to non-const cannot be bound to an rvalue and that an rvalue reference cannot be bound to an
lvalue can affect the viability of the function (see 16.3.3.1.4).
16.3.3
Best viable function
[over.match.best]
1
Define ICSi(F) as follows:
(1.1)
If F is a static member function, ICS1 (F) is defined such that ICS1 (F) is neither better nor worse than
ICS1 (G) for any function G, and, symmetrically, ICS1 (G) is neither better nor worse than ICS1 (F);132
otherwise,
(1.2)
let ICSi(F) denote the implicit conversion sequence that converts the i-th argument in the list to the
type of the i-th parameter of viable function F. 16.3.3.1 defines the implicit conversion sequences and
16.3.3.2 defines what it means for one implicit conversion sequence to be a better conversion sequence
or worse conversion sequence than another.
Given these definitions, a viable function F1 is defined to be a better function than another viable function
F2 if for all arguments i, ICSi(F1) is not a worse conversion sequence than ICSi(F2), and then
(1.3)
for some argument j, ICSj(F1) is a better conversion sequence than ICSj(F2), or, if not that,
131) According to 11.3.6, parameters following the (m+1)-st parameter must also have default arguments.
132) If a function is a static member function, this definition means that the first argument, the implied object argument, has no
effect in the determination of whether the function is better or worse than any other function.
§ 16.3.3
287
(1.4)
the context is an initialization by user-defined conversion (see 11.6, 16.3.1.5, and 16.3.1.6) and the
standard conversion sequence from the return type of F1 to the destination type (i.e., the type of the
entity being initialized) is a better conversion sequence than the standard conversion sequence from the
return type of F2 to the destination type [ Example:
struct A {
A();
operator int();
operator double();
} a;
int i = a;
// a.operator int() followed by no conversion is better than
// a.operator double() followed by a conversion to int
float x = a;
// ambiguous: both possibilities require conversions,
// and neither is better than the other
— end example ] or, if not that,
(1.5)
the context is an initialization by conversion function for direct reference binding (16.3.1.6) of a reference
to function type, the return type of F1 is the same kind of reference (lvalue or rvalue) as the reference
being initialized, and the return type of F2 is not [ Example:
template <class T> struct A {
operator T&();
// #1
operator T&&();
// #2
};
typedef int Fn();
A<Fn> a;
Fn& lf = a;
// calls #1
Fn&& rf = a;
// calls #2
— end example ] or, if not that,
(1.6)
F1 is not a function template specialization and F2 is a function template specialization, or, if not that,
(1.7)
F1 and F2 are function template specializations, and the function template for F1 is more specialized
than the template for F2 according to the partial ordering rules described in 17.6.6.2, or, if not that,
(1.8)
F1 and F2 are non-template functions with the same parameter-type-lists, and F1 is more constrained
than F2 according to the partial ordering of constraints described in 17.4.4, or if not that,
(1.9)
F1 is a constructor for a class D, F2 is a constructor for a base class B of D, and for all arguments the
corresponding parameters of F1 and F2 have the same type. [ Example:
struct A {
A(int = 0);
};
struct B: A {
using A::A;
B();
};
int main() {
B b;
// OK, B::B()
}
— end example ] or, if not that,
(1.10)
F1 is an operator function for a relational (8.5.9) or equality (8.5.10) operator and F2 is an operator
function for a three-way comparison operator (8.5.8) [ Example:
struct S {
auto operator<=>(const S&, const S&) = default; // #1
bool operator<(const S&, const S&);
// #2
};
bool b = S() < S();
// calls #2
— end example ] or, if not that,
(1.11)
F1 and F2 are operator functions for operator<=> and F2 is a synthesized candidate with reversed
order of parameters and F1 is not [ Example:
§
16.3.3
288
struct S {
std::weak_ordering operator<=>(const S&, int);
// #1
std::weak_ordering operator<=>(int, const S&);
// #2
};
bool b = 1 < S();
// calls #2
— end example ] or, if not that
(1.12)
F1 is generated from a deduction-guide (16.3.1.8) and F2 is not, or, if not that,
(1.13)
F1 is the copy deduction candidate (16.3.1.8) and F2 is not, or, if not that,
(1.14)
F1 is generated from a non-template constructor and F2 is generated from a constructor template.
[ Example:
template <class T> struct A {
using value_type = T;
A(value_type);
// #1
A(const A&);
// #2
A(T, T, int);
// #3
template<class U>
A(int, T, U);
// #4
// #5 is the copy deduction candidate, A(A)
};
A x(1, 2, 3);
// uses #3, generated from a non-template constructor
template <class T>
A(T) -> A<T>;
// #6, less specialized than #5
A a(42);
// uses #6 to deduce A<int> and #1 to initialize
A b = a;
// uses #5 to deduce A<int> and #2 to initialize
template <class T>
A(A<T>) -> A<A<T>>; // #7, as specialized as #5
A b2 = a;
// uses #7 to deduce A<A<int>> and #1 to initialize
— end example ]
2
If
there is exactly one viable function that is a better function than all other viable functions, then it is the
one selected by overload resolution; otherwise the call is ill-formed.133 [ Example:
void Fcn(const int*, short);
void Fcn(int*, int);
int i;
short s = 0;
void f() {
Fcn(&i, s);
// is ambiguous because &i → int* is better than &i → const int*
// but s → short is also better than s → int
Fcn(&i, 1L);
// calls Fcn(int*, int), because &i → int* is better than &i → const int*
// and 1L → short and 1L → int are indistinguishable
Fcn(&i, ’c’);
// calls Fcn(int*, int), because &i → int* is better than &i → const int*
// and c → int is better than c → short
}
— end example ]
133) The algorithm for selecting the best viable function is linear in the number of viable functions. Run a simple tournament
to find a function W that is not worse than any opponent it faced. Although another function F that W did not face might be at
least as good as W, F cannot be the best function because at some point in the tournament F encountered another function G
such that F was not better than G. Hence, W is either the best function or there is no best function. So, make a second pass over
the viable functions to verify that W is better than all other functions.
§ 16.3.3
289
3
If the best viable function resolves to a function for which multiple declarations were found, and if at least
two of these declarations — or the declarations they refer to in the case of using-declarations — specify a
default argument that made the function viable, the program is ill-formed. [ Example:
namespace A {
extern "C" void f(int = 5);
}
namespace B {
extern "C" void f(int = 5);
}
using A::f;
using B::f;
void use() {
f(3);
// OK, default argument was not used for viability
f();
// error: found default argument twice
}
— end example ]
16.3.3.1
Implicit conversion sequences
[over.best.ics]
1
An implicit conversion sequence is a sequence of conversions used to convert an argument in a function call
to the type of the corresponding parameter of the function being called. The sequence of conversions is an
implicit conversion as defined in Clause 7, which means it is governed by the rules for initialization of an
object or reference by a single expression (11.6, 11.6.3).
2
Implicit conversion sequences are concerned only with the type, cv-qualification, and value category of the
argument and how these are converted to match the corresponding properties of the parameter. Other
properties, such as the lifetime, storage class, alignment, accessibility of the argument, whether the argument
is a bit-field, and whether a function is deleted (11.4.3), are ignored. So, although an implicit conversion
sequence can be defined for a given argument-parameter pair, the conversion from the argument to the
parameter might still be ill-formed in the final analysis.
3
A well-formed implicit conversion sequence is one of the following forms:
(3.1)
a standard conversion sequence (16.3.3.1.1),
(3.2)
a user-defined conversion sequence (16.3.3.1.2), or
(3.3)
an ellipsis conversion sequence (16.3.3.1.3).
4
However, if the target is
(4.1)
the first parameter of a constructor or
(4.2)
the implicit object parameter of a user-defined conversion function
and the constructor or user-defined conversion function is a candidate by
(4.3)
16.3.1.3, when the argument is the temporary in the second step of a class copy-initialization,
(4.4)
16.3.1.4, 16.3.1.5, or 16.3.1.6 (in all cases), or
(4.5)
the second phase of 16.3.1.7 when the initializer list has exactly one element that is itself an initializer
list, and the target is the first parameter of a constructor of class X, and the conversion is to X or
reference to cv X,
user-defined conversion sequences are not considered. [ Note: These rules prevent more than one user-defined
conversion from being applied during overload resolution, thereby avoiding infinite recursion.
— end note ]
[ Example:
struct Y { Y(int); };
struct A { operator int(); };
Y y1 = A();
// error: A::operator int() is not a candidate
struct X { };
struct B { operator X(); };
B b;
X x({b});
// error: B::operator X() is not a candidate
§ 16.3.3.1
290
— end example ]
5
For the case where the parameter type is a reference, see 16.3.3.1.4.
6
When the parameter type is not a reference, the implicit conversion sequence models a copy-initialization of
the parameter from the argument expression. The implicit conversion sequence is the one required to convert
the argument expression to a prvalue of the type of the parameter. [ Note: When the parameter has a class
type, this is a conceptual conversion defined for the purposes of Clause 16; the actual initialization is defined
in terms of constructors and is not a conversion.
— end note ] Any difference in top-level cv-qualification is
subsumed by the initialization itself and does not constitute a conversion. [ Example: A parameter of type A
can be initialized from an argument of type const A. The implicit conversion sequence for that case is the
identity sequence; it contains no “conversion” from const A to A. — end example ] When the parameter has
a class type and the argument expression has the same type, the implicit conversion sequence is an identity
conversion. When the parameter has a class type and the argument expression has a derived class type,
the implicit conversion sequence is a derived-to-base Conversion from the derived class to the base class.
[ Note: There is no such standard conversion; this derived-to-base Conversion exists only in the description of
implicit conversion sequences.
— end note ] A derived-to-base Conversion has Conversion rank (16.3.3.1.1).
7
In all contexts, when converting to the implicit object parameter or when converting to the left operand of
an assignment operation only standard conversion sequences are allowed.
8
If no conversions are required to match an argument to a parameter type, the implicit conversion sequence is
the standard conversion sequence consisting of the identity conversion (16.3.3.1.1).
9
If no sequence of conversions can be found to convert an argument to a parameter type, an implicit conversion
sequence cannot be formed.
10
If several different sequences of conversions exist that each convert the argument to the parameter type, the
implicit conversion sequence associated with the parameter is defined to be the unique conversion sequence
designated the ambiguous conversion sequence. For the purpose of ranking implicit conversion sequences as
described in 16.3.3.2, the ambiguous conversion sequence is treated as a user-defined conversion sequence
that is indistinguishable from any other user-defined conversion sequence.
[Note: This rule prevents a
function from becoming non-viable because of an ambiguous conversion sequence for one of its parameters.
[ Example:
class B;
class A { A (B&);};
class B { operator A (); };
class C { C (B&); };
void f(A) { }
void f(C) { }
B b;
f(b);
// ill-formed: ambiguous because there is a conversion b → C (via constructor)
// and an (ambiguous) conversion b → A (via constructor or conversion function)
void f(B) { }
f(b);
// OK, unambiguous
— end example ]
— end note ] If a function that uses the ambiguous conversion sequence is selected as the
best viable function, the call will be ill-formed because the conversion of one of the arguments in the call is
ambiguous.
11
The three forms of implicit conversion sequences mentioned above are defined in the following subclauses.
16.3.3.1.1
Standard conversion sequences
[over.ics.scs]
1
Table 13 summarizes the conversions defined in Clause 7 and partitions them into four disjoint categories:
Lvalue Transformation, Qualification Adjustment, Promotion, and Conversion. [ Note: These categories are
orthogonal with respect to value category, cv-qualification, and data representation: the Lvalue Transforma-
tions do not change the cv-qualification or data representation of the type; the Qualification Adjustments do
not change the value category or data representation of the type; and the Promotions and Conversions do
not change the value category or cv-qualification of the type.
— end note ]
2
[Note: As described in Clause 7, a standard conversion sequence is either the Identity conversion by itself
(that is, no conversion) or consists of one to three conversions from the other four categories. If there
are two or more conversions in the sequence, the conversions are applied in the canonical order: Lvalue
Transformation, Promotion or Conversion, Qualification Adjustment. — end note ]
§ 16.3.3.1.1
291

 

 

 

 

 

 

 

Content      ..     8      9      10      11     ..