This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 115e. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.
2024-11-11
[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?
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.
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: