Created on 2016-04-17.00:00:00 last changed 47 months ago
Proposed resolution (November, 2017)
Change 13.9.2 [temp.inst] paragraph 2, breaking the running text into bullets, as follows:
The implicit instantiation of a class template specialization causes
the implicit instantiation of the declarations, but not of the definitions,
default arguments, or noexcept-specifiersof the non-deleted class member functions, member classes, scoped member enumerations, static data members, member templates, and friends; and
it causesthe implicit instantiation of the definitions of deleted member functions, unscoped member enumerations, and member anonymous unions.The implicit instantiation of a class template specialization does not cause the implicit instantiation of default arguments or noexcept-specifiers of the class member functions. [Example:
template<class T> struct C { void f() { T x; } void g() = delete; }; C<void> c; // OK, definition of C<void>::f is not instantiated at this point template<> void C<int>::g() { } // error: redefinition of C<int>::g—end example] However, for the purpose of determining whether an instantiated redeclaration is valid according to 6.3 [basic.def.odr] and 11.4 [class.mem], a declaration that corresponds to a definition in the template is considered to be a definition. [Example:
Notes from the December, 2016 teleconference:
=delete definitions of member functions should be instantiated when instantiating a class template. That would make the example an ill-formed redefinition.
[Accepted as a DR at the March, 2018 (Jacksonville) meeting.]
Although the Standard allows for explicitly specializing a deleted function template, member function of a class template, or member function template with a non-deleted definition, this seems to be problematic for non-template member functions of class templates. For example:
template<typename T> struct A { A(const A&) = delete; A(A&&) = default; }; static_assert(is_trivially_copyable(A<int>)); template<> struct A<int>::A(const A&) { /* ... */ } static_assert(is_trivially_copyable(A<int>)); template<typename T> struct B { virtual void f() = delete; }; struct C : B<int> { void f() override = delete; }; // ok, overriding deleted with deleted template<> void B<int>::f() {} // would make C retroactively ill-formed?
History | |||
---|---|---|---|
Date | User | Action | Args |
2020-12-15 00:00:00 | admin | set | status: dr -> cd5 |
2018-04-11 00:00:00 | admin | set | status: tentatively ready -> dr |
2018-02-27 00:00:00 | admin | set | messages: + msg5872 |
2018-02-27 00:00:00 | admin | set | status: open -> tentatively ready |
2017-02-06 00:00:00 | admin | set | messages: + msg5844 |
2016-04-17 00:00:00 | admin | create |