92 lines
3.8 KiB
Markdown
92 lines
3.8 KiB
Markdown
[diff.cpp17.class]
|
||
|
||
# Annex C (informative) Compatibility [[diff]](./#diff)
|
||
|
||
## C.3 C++ and ISO C++ 2017 [[diff.cpp17]](diff.cpp17#class)
|
||
|
||
### C.3.6 [[class]](class "11 Classes"): classes [diff.cpp17.class]
|
||
|
||
[1](#1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L1125)
|
||
|
||
**Affected subclauses:** [[class.ctor]](class.ctor) and [[class.conv.fct]](class.conv.fct)
|
||
|
||
|
||
**Change:** The class name can no longer be used parenthesized
|
||
immediately after an explicit [*decl-specifier*](dcl.spec.general#nt:decl-specifier "9.2.1 General [dcl.spec.general]") in a constructor declaration[.](#1.sentence-1)
|
||
|
||
The [*conversion-function-id*](class.conv.fct#nt:conversion-function-id "11.4.8.3 Conversion functions [class.conv.fct]") can no longer be used parenthesized
|
||
immediately after an explicit [*decl-specifier*](dcl.spec.general#nt:decl-specifier "9.2.1 General [dcl.spec.general]") in a conversion function declaration[.](#1.sentence-2)
|
||
|
||
|
||
|
||
|
||
**Rationale:** Necessary for new functionality[.](#1.sentence-3)
|
||
|
||
|
||
|
||
|
||
**Effect on original feature:** Valid C++ 2017 code may fail to compile
|
||
in this revision of C++[.](#1.sentence-4)
|
||
|
||
[*Example [1](#example-1)*: struct S {explicit (S)(const S&); // ill-formed; previously well-formedexplicit (operator int)(); // ill-formed; previously well-formedexplicit(true) (S)(int); // OK}; â *end example*]
|
||
|
||
[2](#2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L1148)
|
||
|
||
**Affected subclauses:** [[class.ctor]](class.ctor) and [[class.dtor]](class.dtor)
|
||
|
||
|
||
**Change:** A [*simple-template-id*](temp.names#nt:simple-template-id "13.3 Names of template specializations [temp.names]") is no longer valid as the [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1 General [dcl.decl.general]") of a constructor or destructor[.](#2.sentence-1)
|
||
|
||
|
||
|
||
|
||
**Rationale:** Remove potentially error-prone option for redundancy[.](#2.sentence-2)
|
||
|
||
|
||
|
||
|
||
**Effect on original feature:** Valid C++ 2017 code may fail to compile
|
||
in this revision of C++[.](#2.sentence-3)
|
||
|
||
[*Example [2](#example-2)*: template<class T>struct A { A<T>(); // error: [*simple-template-id*](temp.names#nt:simple-template-id "13.3 Names of template specializations [temp.names]") not allowed for constructor A(int); // OK, injected-class-name used~A<T>(); // error: [*simple-template-id*](temp.names#nt:simple-template-id "13.3 Names of template specializations [temp.names]") not allowed for destructor}; â *end example*]
|
||
|
||
[3](#3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L1168)
|
||
|
||
**Affected subclause:** [[class.copy.elision]](class.copy.elision)
|
||
|
||
|
||
**Change:** A function returning an implicitly movable entity
|
||
may invoke a constructor taking an rvalue reference to a type
|
||
different from that of the returned expression[.](#3.sentence-1)
|
||
|
||
Function and catch-clause parameters can be thrown using move constructors[.](#3.sentence-2)
|
||
|
||
|
||
|
||
|
||
**Rationale:** Side effect of making it easier to write
|
||
more efficient code that takes advantage of moves[.](#3.sentence-3)
|
||
|
||
|
||
|
||
|
||
**Effect on original feature:** Valid C++ 2017 code may fail to compile or have different semantics
|
||
in this revision of C++[.](#3.sentence-4)
|
||
|
||
[*Example [3](#example-3)*: struct base { base();
|
||
base(base const &);private: base(base &&);};
|
||
|
||
struct derived : base {};
|
||
|
||
base f(base b) {throw b; // error: base(base &&) is private derived d; return d; // error: base(base &&) is private}struct S { S(const char *s) : m(s) { } S(const S&) = default;
|
||
S(S&& other) : m(other.m) { other.m = nullptr; }const char * m;};
|
||
|
||
S consume(S&& s) { return s; }void g() { S s("text");
|
||
consume(static_cast<S&&>(s)); char c = *s.m; // undefined behavior; previously ok} â *end example*]
|