Mat*_*lia 17 c++ templates template-specialization deleted-functions c++11
使用旧版本的g ++(4.8.0,MinGW)编译项目我发现此代码无法编译:
template<typename T>
void foo() = delete;
template<>
void foo<int>(){}
int main() {
foo<int>();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
似乎g ++甚至没有尝试寻找显式特化,如果它看到基本情况被删除.
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.
Run Code Online (Sandbox Code Playgroud)
相反,g ++ 4.8.4和5.2(在Linux上)不抱怨.这是旧版本编译器中的错误还是标准中的灰色区域?
附录
clang 3.4.1似乎也不喜欢它:
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
Run Code Online (Sandbox Code Playgroud)
(和@Baum mit Augen在评论报告中它仍然无法在3.7中工作)
我不知道以下是否具有启发性,但我发现了缺陷报告941:已删除的功能模板的显式特化,状态为C++ 11 ,表明以下内容(强调我的):
根据14.7.3 [temp.expl.spec]第1段,只有非删除的函数模板可以明确专门化.然而,似乎没有迫切需要这种限制,并且禁止使用隐式实例化的特化,同时仍然允许使用显式专用版本可能是有用的.
拟议决议(2010年2月):
更改14.7.3 [temp.expl.spec]第1段如下:
以下任何一种明确的专业化:
非删除功能模板类模板
非删除类模板的成员函数类模板的静态数据成员
类模板的成员类
类或类模板的成员类模板
非删除类或类模板的成员函数模板可以宣布......
现在标准草案N4527的当前状态是14.7.3显式专门化[temp.expl.spec]:
1以下任何一项的明确专业化:
(1.1) - 功能模板
(1.2) - 类模板
(1.3) - 变量模板
(1.4) - 类模板的成员函数
(1.5) - 类模板的静态数据成员
(1.6) - 类模板的成员类
(1.7) - 类模板的成员枚举
(1.8) - 类或类模板的成员类模板
(1.9) - 类或类模板的成员函数模板
...
所以我想:
template<typename T>
void foo() = delete;
template<>
void foo<int>(){}
int main() {
foo<int>();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
是C++ 11标准兼容代码,应该被接受.