删除“通用"的专用模板函数案例无法使用 g++ <=4.8.0 和 clang++ 编译

Specialized template function with deleted quot;generalquot; case fails to compile with g++ lt;=4.8.0 and clang++(删除“通用的专用模板函数案例无法使用 g++ lt;=4.8.0 和 clang++ 编译)
本文介绍了删除“通用"的专用模板函数案例无法使用 g++ <=4.8.0 和 clang++ 编译的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

用旧版本的g++(4.8.0,MinGW)编译项目我发现这段代码编译失败:

Compiling a project with an older version of g++ (4.8.0, MinGW) I found that this code fails to compile:

template<typename T>
void foo() = delete;

template<>
void foo<int>(){}

int main() {
    foo<int>();
    return 0;
}

如果 g++ 看到基本情况被删除,它似乎甚至不会尝试寻找显式特化.

It seems that g++ doesn't even try to look for explicit specializations if it sees that the base case is deleted.

mitalia@mitalia:~/scratch$ /opt/mingw32-dw2/bin/i686-w64-mingw32-g++ -std=c++11 buggy_deleted_template.cpp 
buggy_deleted_template.cpp: In function 'int main()':
buggy_deleted_template.cpp:8:14: error: use of deleted function 'void foo() [with T = int]'
     foo<int>();
              ^
buggy_deleted_template.cpp:5:6: error: declared here
 void foo<int>(){}
      ^
mitalia@mitalia:~/scratch$ /opt/mingw32-dw2/bin/i686-w64-mingw32-g++ --version 
i686-w64-mingw32-g++ (rubenvb-4.8.0) 4.8.0
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

相反,g++ 4.8.4 和 5.2(在 Linux 上)不会抱怨.这是老版本编译器的BUG还是标准的灰色地带?

Instead, g++ 4.8.4 and 5.2 (on Linux) do not complain. Is this a bug in the older version of the compiler or a gray area in the standard?

附录

clang 3.4.1 似乎也不喜欢它:

clang 3.4.1 too seems not to like it:

mitalia@mitalia:~/scratch$ clang++ -std=c++11 buggy_deleted_template.cpp                                                             
buggy_deleted_template.cpp:5:6: error: redefinition of 'foo'                                                                         
void foo<int>(){}
     ^
buggy_deleted_template.cpp:5:6: note: previous definition is here
buggy_deleted_template.cpp:8:5: error: no matching function for call to 'foo'
    foo<int>();
    ^~~~~~~~
buggy_deleted_template.cpp:2:6: note: candidate template ignored: substitution failure [with T = int]
void foo() = delete;
     ^
2 errors generated.
mitalia@mitalia:~/scratch$ clang++ --version
Ubuntu clang version 3.4-1ubuntu3 (tags/RELEASE_34/final) (based on LLVM 3.4)
Target: x86_64-pc-linux-gnu
Thread model: posix

(和 @Baum mit Augen 在评论中报告说它在 3.7 中仍然不起作用)

(and @Baum mit Augen in the comments reports that it still doesn't work in 3.7)

推荐答案

我不知道以下内容是否有启发,但我发现了 缺陷报告 941:已删除函数模板的显式特化 ,状态为 C++11,声明如下<强>(强调我的):

I don't know if the following will be enlightening but I found defect report 941: Explicit specialization of deleted function template with status C++11 that states the following (Emphasis Mine):

根据 14.7.3 [temp.expl.spec] 第 1 段,仅未删除函数模板可以被明确地专门化.没有然而,似乎是对这一限制的迫切需要,而且它可能有助于禁止使用隐式实例化专业化,同时仍然允许使用显式专业化版本.

According to 14.7.3 [temp.expl.spec] paragraph 1, only non-deleted function templates may be explicitly specialized. There doesn't appear to be a compelling need for this restriction, however, and it could be useful to forbid use of implicitly-instantiated specializations while still allowing use of explicitly-specialized versions.

提议的决议(2010 年 2 月):

Proposed resolution (February, 2010):

将 14.7.3 [temp.expl.spec] 第 1 段更改如下:

Change 14.7.3 [temp.expl.spec] paragraph 1 as follows:

以下任何一项的明确特化:

An explicit specialization of any of the following:

未删除函数模板

类模板

未删除类模板的成员函数

类模板的静态数据成员

类模板的成员类

类或类模板的成员类模板

member class template of a class or class template

未删除 类或类的成员函数模板模板

non-deleted member function template of a class or class template

可以声明...

现在标准草案的现状N4527 是 14.7.3 显式特化 [temp.expl.spec]:

Now the current state of the draft standard N4527 is 14.7.3 Explicit specialization [temp.expl.spec]:

1 以下任何一项的明确特化:

1 An explicit specialization of any of the following:

(1.1) — 函数模板

(1.1) — function template

(1.2) — 类模板

(1.2) — class template

(1.3) — 变量模板

(1.3) — variable template

(1.4) — 类模板的成员函数

(1.4) — member function of a class template

(1.5) — 类模板的静态数据成员

(1.5) — static data member of a class template

(1.6) — 类模板的成员类

(1.6) — member class of a class template

(1.7) — 类模板的成员枚举

(1.7) — member enumeration of a class template

(1.8) — 类或类模板的成员类模板

(1.8) — member class template of a class or class template

(1.9) — 类或类模板的成员函数模板

(1.9) — member function template of a class or class template

...

所以我猜:

template<typename T>
void foo() = delete;

template<>
void foo<int>(){}

int main() {
    foo<int>();
    return 0;
}

是 C++11 标准兼容代码,应该被接受.

Is C++11 standard compatible code and should be accepted.

这篇关于删除“通用"的专用模板函数案例无法使用 g++ &lt;=4.8.0 和 clang++ 编译的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

本站部分内容来源互联网,如果有图片或者内容侵犯了您的权益,请联系我们,我们会在确认后第一时间进行删除!

相关文档推荐

How do compilers treat variable length arrays(编译器如何处理变长数组)
Deduce template argument from std::function call signature(从 std::function 调用签名推导出模板参数)
check if member exists using enable_if(使用 enable_if 检查成员是否存在)
Standard Library Containers with additional optional template parameters?(具有附加可选模板参数的标准库容器?)
Uses of a C++ Arithmetic Promotion Header(C++ 算术提升标头的使用)
Parameter pack must be at the end of the parameter list... When and why?(参数包必须位于参数列表的末尾...何时以及为什么?)