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?
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.