問題描述
用舊版本的g++(4.8.0,MinGW)編譯項(xiàng)目我發(fā)現(xiàn)這段代碼編譯失敗:
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++ 看到基本情況被刪除,它似乎甚至不會(huì)嘗試尋找顯式特化.
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 上)不會(huì)抱怨.這是老版本編譯器的BUG還是標(biāo)準(zhǔn)的灰色地帶?
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 在評(píng)論中報(bào)告說它在 3.7 中仍然不起作用)
(and @Baum mit Augen in the comments reports that it still doesn't work in 3.7)
推薦答案
我不知道以下內(nèi)容是否有啟發(fā),但我發(fā)現(xiàn)了 缺陷報(bào)告 941:已刪除函數(shù)模板的顯式特化 ,狀態(tài)為 C++11,聲明如下<強(qiáng)>(強(qiáng)調(diào)我的):
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):
根據(jù) 14.7.3 [temp.expl.spec] 第 1 段,僅未刪除函數(shù)模板可以被明確地專門化.沒有然而,似乎是對(duì)這一限制的迫切需要,而且它可能有助于禁止使用隱式實(shí)例化專業(yè)化,同時(shí)仍然允許使用顯式專業(yè)化版本.
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:
以下任何一項(xiàng)的明確特化:
An explicit specialization of any of the following:
未刪除函數(shù)模板
類模板
未刪除類模板的成員函數(shù)
類模板的靜態(tài)數(shù)據(jù)成員
類模板的成員類
類或類模板的成員類模板
member class template of a class or class template
未刪除 類或類的成員函數(shù)模板模板
non-deleted member function template of a class or class
template
可以聲明...
現(xiàn)在標(biāo)準(zhǔn)草案的現(xiàn)狀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 以下任何一項(xiàng)的明確特化:
1 An explicit specialization of any of the following:
(1.1) — 函數(shù)模板
(1.1) — function template
(1.2) — 類模板
(1.2) — class template
(1.3) — 變量模板
(1.3) — variable template
(1.4) — 類模板的成員函數(shù)
(1.4) — member function of a class template
(1.5) — 類模板的靜態(tài)數(shù)據(jù)成員
(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) — 類或類模板的成員函數(shù)模板
(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 標(biāo)準(zhǔn)兼容代碼,應(yīng)該被接受.
Is C++11 standard compatible code and should be accepted.
這篇關(guān)于刪除“通用"的專用模板函數(shù)案例無法使用 g++ <=4.8.0 和 clang++ 編譯的文章就介紹到這了,希望我們推薦的答案對(duì)大家有所幫助,也希望大家多多支持html5模板網(wǎng)!