在 C++ 中显式实例化已删除的函数模板
Explicit instantiation of a deleted function template in C++
如果函数模板被标记为已删除,是否允许像示例中那样显式实例化它:
template<class T>
int foo(T) = delete;
template int foo(int);
Clang 和 GCC 允许,而 MSVC 打印错误:
error C2280: 'int foo<int>(int)': attempting to reference a deleted function
演示:https://gcc.godbolt.org/z/49hfqnr4f
哪个编译器就在这里?
Clang 和 GCC 是对的。 MSVC 可能指的是以下规则 ([dcl.fct.def.delete]/2):
A program that refers to a deleted function implicitly or explicitly, other than to declare it, is ill-formed.
显式实例化定义是声明,因此是允许的。
不过,公平地说,在这种情况下,“指代”的含义尚不清楚,因此语言律师有一定的空间。但很明显,一般来说,只允许实例化模板来生成已删除的函数定义。 [temp.inst]/3.2 还提到了在class 模板被隐式实例化时发生的已删除成员函数的隐式实例化。如果实例化模板化实体以生成已删除的函数定义的格式不正确,则无法使用 class 模板,例如 std::atomic
具有已删除的复制构造函数。您的程序只是显式地执行在这些情况下隐式发生的事情。
如果函数模板被标记为已删除,是否允许像示例中那样显式实例化它:
template<class T>
int foo(T) = delete;
template int foo(int);
Clang 和 GCC 允许,而 MSVC 打印错误:
error C2280: 'int foo<int>(int)': attempting to reference a deleted function
演示:https://gcc.godbolt.org/z/49hfqnr4f
哪个编译器就在这里?
Clang 和 GCC 是对的。 MSVC 可能指的是以下规则 ([dcl.fct.def.delete]/2):
A program that refers to a deleted function implicitly or explicitly, other than to declare it, is ill-formed.
显式实例化定义是声明,因此是允许的。
不过,公平地说,在这种情况下,“指代”的含义尚不清楚,因此语言律师有一定的空间。但很明显,一般来说,只允许实例化模板来生成已删除的函数定义。 [temp.inst]/3.2 还提到了在class 模板被隐式实例化时发生的已删除成员函数的隐式实例化。如果实例化模板化实体以生成已删除的函数定义的格式不正确,则无法使用 class 模板,例如 std::atomic
具有已删除的复制构造函数。您的程序只是显式地执行在这些情况下隐式发生的事情。