Init
This commit is contained in:
254
cppdraft/class/conv.md
Normal file
254
cppdraft/class/conv.md
Normal file
@@ -0,0 +1,254 @@
|
||||
[class.conv]
|
||||
|
||||
# 11 Classes [[class]](./#class)
|
||||
|
||||
## 11.4 Class members [[class.mem]](class.mem#class.conv)
|
||||
|
||||
### 11.4.8 Conversions [class.conv]
|
||||
|
||||
#### [11.4.8.1](#general) General [[class.conv.general]](class.conv.general)
|
||||
|
||||
[1](#general-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2441)
|
||||
|
||||
Type conversions of class objects can be specified by constructors and
|
||||
by conversion functions[.](#general-1.sentence-1)
|
||||
|
||||
These conversions are called[*user-defined conversions*](#def:conversion,user-defined "11.4.8.1 General [class.conv.general]") and are used for implicit type conversions ([[conv]](conv "7.3 Standard conversions")),
|
||||
for initialization ([[dcl.init]](dcl.init "9.5 Initializers")),
|
||||
and for explicit type conversions ([[expr.type.conv]](expr.type.conv "7.6.1.4 Explicit type conversion (functional notation)"), [[expr.cast]](expr.cast "7.6.3 Explicit type conversion (cast notation)"), [[expr.static.cast]](expr.static.cast "7.6.1.9 Static cast"))[.](#general-1.sentence-2)
|
||||
|
||||
[2](#general-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2455)
|
||||
|
||||
User-defined conversions are applied only where they are unambiguous ([[class.member.lookup]](class.member.lookup "6.5.2 Member name lookup"), [[class.conv.fct]](#fct "11.4.8.3 Conversion functions"))[.](#general-2.sentence-1)
|
||||
|
||||
Conversions obey the access control rules ([[class.access]](class.access "11.8 Member access control"))[.](#general-2.sentence-2)
|
||||
|
||||
Access control is applied after ambiguity resolution ([[basic.lookup]](basic.lookup "6.5 Name lookup"))[.](#general-2.sentence-3)
|
||||
|
||||
[3](#general-3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2460)
|
||||
|
||||
[*Note [1](#general-note-1)*:
|
||||
|
||||
See [[over.match]](over.match "12.2 Overload resolution") for a discussion of the use of conversions in function calls[.](#general-3.sentence-1)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[4](#general-4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2465)
|
||||
|
||||
At most one user-defined conversion (constructor or conversion function)
|
||||
is implicitly applied to a single value[.](#general-4.sentence-1)
|
||||
|
||||
[*Example [1](#general-example-1)*: struct X {operator int();};
|
||||
|
||||
struct Y {operator X();};
|
||||
|
||||
Y a;int b = a; // error: no viable conversion (a.operator X().operator int() not considered)int c = X(a); // OK, a.operator X().operator int() â *end example*]
|
||||
|
||||
#### [11.4.8.2](#ctor) Conversion by constructor [[class.conv.ctor]](class.conv.ctor)
|
||||
|
||||
[1](#ctor-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2488)
|
||||
|
||||
A constructor that is not explicit ([[dcl.fct.spec]](dcl.fct.spec "9.2.3 Function specifiers"))
|
||||
specifies a conversion from
|
||||
the types of its parameters (if any)
|
||||
to the type of its class[.](#ctor-1.sentence-1)
|
||||
|
||||
[*Example [1](#ctor-example-1)*:
|
||||
|
||||
[ð](#:Jessie)
|
||||
|
||||
struct X { X(int);
|
||||
X(const char*, int = 0);
|
||||
X(int, int);};
|
||||
|
||||
void f(X arg) { X a = 1; // a = X(1) X b = "Jessie"; // b = X("Jessie",0) a = 2; // a = X(2) f(3); // f(X(3)) f({1, 2}); // f(X(1,2))} â *end example*]
|
||||
|
||||
[2](#ctor-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2512)
|
||||
|
||||
[*Note [1](#ctor-note-1)*:
|
||||
|
||||
An explicit constructor constructs objects just like non-explicit
|
||||
constructors, but does so only where the direct-initialization syntax ([[dcl.init]](dcl.init "9.5 Initializers"))
|
||||
or where casts ([[expr.static.cast]](expr.static.cast "7.6.1.9 Static cast"), [[expr.cast]](expr.cast "7.6.3 Explicit type conversion (cast notation)")) are explicitly
|
||||
used; see also [[over.match.copy]](over.match.copy "12.2.2.5 Copy-initialization of class by user-defined conversion")[.](#ctor-2.sentence-1)
|
||||
|
||||
A default constructor can be an explicit constructor; such a constructor
|
||||
will be used to perform default-initialization
|
||||
or value-initialization ([[dcl.init]](dcl.init "9.5 Initializers"))[.](#ctor-2.sentence-2)
|
||||
|
||||
[*Example [2](#ctor-example-2)*: struct Z {explicit Z(); explicit Z(int); explicit Z(int, int);};
|
||||
|
||||
Z a; // OK, default-initialization performed Z b{}; // OK, direct initialization syntax used Z c = {}; // error: copy-list-initialization Z a1 = 1; // error: no implicit conversion Z a3 = Z(1); // OK, direct initialization syntax used Z a2(1); // OK, direct initialization syntax used Z* p = new Z(1); // OK, direct initialization syntax used Z a4 = (Z)1; // OK, explicit cast used Z a5 = static_cast<Z>(1); // OK, explicit cast used Z a6 = { 3, 4 }; // error: no implicit conversion â *end example*]
|
||||
|
||||
â *end note*]
|
||||
|
||||
#### [11.4.8.3](#fct) Conversion functions [[class.conv.fct]](class.conv.fct)
|
||||
|
||||
[conversion-function-id:](#nt:conversion-function-id "11.4.8.3 Conversion functions [class.conv.fct]")
|
||||
operator [*conversion-type-id*](#nt:conversion-type-id "11.4.8.3 Conversion functions [class.conv.fct]")
|
||||
|
||||
[conversion-type-id:](#nt:conversion-type-id "11.4.8.3 Conversion functions [class.conv.fct]")
|
||||
[*type-specifier-seq*](dcl.type.general#nt:type-specifier-seq "9.2.9.1 General [dcl.type.general]") [*conversion-declarator*](#nt:conversion-declarator "11.4.8.3 Conversion functions [class.conv.fct]")opt
|
||||
|
||||
[conversion-declarator:](#nt:conversion-declarator "11.4.8.3 Conversion functions [class.conv.fct]")
|
||||
[*ptr-operator*](dcl.decl.general#nt:ptr-operator "9.3.1 General [dcl.decl.general]") [*conversion-declarator*](#nt:conversion-declarator "11.4.8.3 Conversion functions [class.conv.fct]")opt
|
||||
|
||||
[1](#fct-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2563)
|
||||
|
||||
A declaration
|
||||
whose [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1 General [dcl.decl.general]") has
|
||||
an [*unqualified-id*](expr.prim.id.unqual#nt:unqualified-id "7.5.5.2 Unqualified names [expr.prim.id.unqual]") that is a [*conversion-function-id*](#nt:conversion-function-id "11.4.8.3 Conversion functions [class.conv.fct]") declares a [*conversion function*](#def:function,conversion "11.4.8.3 Conversion functions [class.conv.fct]");
|
||||
its [*declarator*](dcl.decl.general#nt:declarator "9.3.1 General [dcl.decl.general]") shall be
|
||||
a function declarator ([[dcl.fct]](dcl.fct "9.3.4.6 Functions")) of the form
|
||||
|
||||
[*noptr-declarator*](dcl.decl.general#nt:noptr-declarator "9.3.1 General [dcl.decl.general]") [*parameters-and-qualifiers*](dcl.decl.general#nt:parameters-and-qualifiers "9.3.1 General [dcl.decl.general]")
|
||||
|
||||
where the [*noptr-declarator*](dcl.decl.general#nt:noptr-declarator "9.3.1 General [dcl.decl.general]") consists solely of
|
||||
an [*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1 General [expr.prim.id.general]"),
|
||||
an optional [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]"), and
|
||||
optional surrounding parentheses, and
|
||||
the [*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") has one of the following forms:
|
||||
|
||||
- [(1.1)](#fct-1.1)
|
||||
|
||||
in a [*member-declaration*](class.mem.general#nt:member-declaration "11.4.1 General [class.mem.general]") that belongs to
|
||||
the [*member-specification*](class.mem.general#nt:member-specification "11.4.1 General [class.mem.general]") of a class or class template
|
||||
but is not a friend declaration ([[class.friend]](class.friend "11.8.4 Friends")),
|
||||
the [*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") is a [*conversion-function-id*](#nt:conversion-function-id "11.4.8.3 Conversion functions [class.conv.fct]");
|
||||
|
||||
- [(1.2)](#fct-1.2)
|
||||
|
||||
otherwise, the [*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") is a [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") whose [*unqualified-id*](expr.prim.id.unqual#nt:unqualified-id "7.5.5.2 Unqualified names [expr.prim.id.unqual]") is a [*conversion-function-id*](#nt:conversion-function-id "11.4.8.3 Conversion functions [class.conv.fct]")[.](#fct-1.sentence-1)
|
||||
|
||||
[2](#fct-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2589)
|
||||
|
||||
A conversion function shall have no non-object parameters and
|
||||
shall be a non-static member function of a class or class template X;
|
||||
its declared return type is the [*conversion-type-id*](#nt:conversion-type-id "11.4.8.3 Conversion functions [class.conv.fct]") and
|
||||
it specifies a conversion from X to
|
||||
the type specified by the [*conversion-type-id*](#nt:conversion-type-id "11.4.8.3 Conversion functions [class.conv.fct]"),
|
||||
interpreted as a [*type-id*](dcl.name#nt:type-id "9.3.2 Type names [dcl.name]") ([[dcl.name]](dcl.name "9.3.2 Type names"))[.](#fct-2.sentence-1)
|
||||
|
||||
A [*decl-specifier*](dcl.spec.general#nt:decl-specifier "9.2.1 General [dcl.spec.general]") in the [*decl-specifier-seq*](dcl.spec.general#nt:decl-specifier-seq "9.2.1 General [dcl.spec.general]") of a conversion function (if any) shall not be
|
||||
a [*defining-type-specifier*](dcl.type.general#nt:defining-type-specifier "9.2.9.1 General [dcl.type.general]")[.](#fct-2.sentence-2)
|
||||
|
||||
[3](#fct-3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2600)
|
||||
|
||||
[*Note [1](#fct-note-1)*:
|
||||
|
||||
A conversion function is never invoked for
|
||||
implicit or explicit conversions of an object
|
||||
to the same object type (or a reference to it),
|
||||
to a base class of that type (or a reference to it),
|
||||
or to cv void[.](#fct-3.sentence-1)
|
||||
|
||||
Even though never directly called to perform a conversion,
|
||||
such conversion functions can be declared and can potentially
|
||||
be reached through a call to a virtual conversion function in a base class[.](#fct-3.sentence-2)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[*Example [1](#fct-example-1)*: struct X {operator int(); operator auto() -> short; // error: trailing return type};
|
||||
|
||||
void f(X a) {int i = int(a);
|
||||
i = (int)a;
|
||||
i = a;}
|
||||
|
||||
In all three cases the value assigned will be converted byX::operator int()[.](#fct-3.sentence-3)
|
||||
|
||||
â *end example*]
|
||||
|
||||
[4](#fct-4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2628)
|
||||
|
||||
A conversion function may be explicit ([[dcl.fct.spec]](dcl.fct.spec "9.2.3 Function specifiers")), in which case it is only considered as a user-defined conversion for direct-initialization ([[dcl.init]](dcl.init "9.5 Initializers"))[.](#fct-4.sentence-1)
|
||||
|
||||
Otherwise, user-defined conversions are not restricted to use in assignments and initializations[.](#fct-4.sentence-2)
|
||||
|
||||
[*Example [2](#fct-example-2)*: class Y { };struct Z {explicit operator Y() const;};
|
||||
|
||||
void h(Z z) { Y y1(z); // OK, direct-initialization Y y2 = z; // error: no conversion function candidate for copy-initialization Y y3 = (Y)z; // OK, cast notation}void g(X a, X b) {int i = (a) ? 1+a : 0; int j = (a&&b) ? a+b : i; if (a) {}} â *end example*]
|
||||
|
||||
[5](#fct-5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2652)
|
||||
|
||||
The[*conversion-type-id*](#nt:conversion-type-id "11.4.8.3 Conversion functions [class.conv.fct]") shall not represent a function type nor an array type[.](#fct-5.sentence-1)
|
||||
|
||||
The[*conversion-type-id*](#nt:conversion-type-id "11.4.8.3 Conversion functions [class.conv.fct]") in a[*conversion-function-id*](#nt:conversion-function-id "11.4.8.3 Conversion functions [class.conv.fct]") is the longest sequence of
|
||||
tokens that could possibly form a [*conversion-type-id*](#nt:conversion-type-id "11.4.8.3 Conversion functions [class.conv.fct]")[.](#fct-5.sentence-2)
|
||||
|
||||
[*Note [2](#fct-note-2)*:
|
||||
|
||||
This prevents ambiguities between the declarator operator * and its expression
|
||||
counterparts[.](#fct-5.sentence-3)
|
||||
|
||||
[*Example [3](#fct-example-3)*: &ac.operator int*i; // syntax error:// parsed as: &(ac.operator int *)i// not as: &(ac.operator int)*i
|
||||
|
||||
The * is the pointer declarator and not the multiplication operator[.](#fct-5.sentence-4)
|
||||
|
||||
â *end example*]
|
||||
|
||||
This rule also prevents ambiguities for attributes[.](#fct-5.sentence-5)
|
||||
|
||||
[*Example [4](#fct-example-4)*: operator int [[noreturn]] (); // error: noreturn attribute applied to a type â *end example*]
|
||||
|
||||
â *end note*]
|
||||
|
||||
[6](#fct-6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2681)
|
||||
|
||||
[*Note [3](#fct-note-3)*:
|
||||
|
||||
A conversion function in a derived class hides only
|
||||
conversion functions in base classes that convert to the same type[.](#fct-6.sentence-1)
|
||||
|
||||
A conversion function template with a dependent return type hides only
|
||||
templates in base classes that correspond to it ([[class.member.lookup]](class.member.lookup "6.5.2 Member name lookup"));
|
||||
otherwise, it hides and is hidden as a non-template function[.](#fct-6.sentence-2)
|
||||
|
||||
Function overload resolution ([[over.match.best]](over.match.best "12.2.4 Best viable function")) selects
|
||||
the best conversion function to perform the conversion[.](#fct-6.sentence-3)
|
||||
|
||||
[*Example [5](#fct-example-5)*: struct X {operator int();};
|
||||
|
||||
struct Y : X {operator char();};
|
||||
|
||||
void f(Y& a) {if (a) { // error: ambiguous between X::operator int() and Y::operator char()}} â *end example*]
|
||||
|
||||
â *end note*]
|
||||
|
||||
[7](#fct-7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2709)
|
||||
|
||||
Conversion functions can be virtual[.](#fct-7.sentence-1)
|
||||
|
||||
[8](#fct-8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2713)
|
||||
|
||||
A conversion function template shall not have a
|
||||
deduced return type ([[dcl.spec.auto]](dcl.spec.auto "9.2.9.7 Placeholder type specifiers"))[.](#fct-8.sentence-1)
|
||||
|
||||
[*Example [6](#fct-example-6)*: struct S {operator auto() const { return 10; } // OKtemplate<class T>operator auto() const { return 1.2; } // error: conversion function template}; â *end example*]
|
||||
Reference in New Issue
Block a user