This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 114a. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.

2024-04-18


2260. Explicit specializations of deleted member functions

Section: 13.9.4  [temp.expl.spec]     Status: CD5     Submitter: Richard Smith     Date: 2016-04-17

[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 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: