c++templateslanguage-lawyerexplicit-instantiationdeleted-functions

Explicit instantiation of a deleted function template in C++


If a function template is marked as deleted, is it allowed to explicitly instantiate it as in the example:

template<class T>
int foo(T) = delete;

template int foo(int);

Clang and GCC allows it, while MSVC prints the error:

error C2280: 'int foo<int>(int)': attempting to reference a deleted function

Demo: https://gcc.godbolt.org/z/49hfqnr4f

Which compiler is right here?


Solution

  • Clang and GCC are right. MSVC is probably referring to the following rule ([dcl.fct.def.delete]/2):

    A program that refers to a deleted function implicitly or explicitly, other than to declare it, is ill-formed.

    An explicit instantiation definition is a declaration, so it is allowed.

    Although, to be fair, it's not clear what "refers" means in this context, so there is some room for language lawyering. But it's clear that, in general, the mere instantiation of a template to produce a deleted function definition is allowed. [temp.inst]/3.2 also mentions the implicit instantiation of deleted member functions that occurs when class templates are implicitly instantiated. If instantiating a templated entity to produce a deleted function definition were ill-formed, it wouldn't be possible to use class templates like std::atomic that have a deleted copy constructor. Your program merely does explicitly what happens implicitly under those circumstances.