[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)*: templatestruct A { A(); // 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(); // 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)); char c = *s.m; // undefined behavior; previously ok} — *end example*]