[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*]
