简体   繁体   English

具有已删除“一般”情况的专用模板功能无法使用g ++ <= 4.8.0和clang ++进行编译

[英]Specialized template function with deleted “general” case fails to compile with g++ <=4.8.0 and clang++

Compiling a project with an older version of g++ (4.8.0, MinGW) I found that this code fails to compile: 使用旧版本的g ++(4.8.0,MinGW)编译项目时,我发现此代码无法编译:

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

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

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

It seems that g++ doesn't even try to look for explicit specializations if it sees that the base case is deleted. 如果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.

Instead, g++ 4.8.4 and 5.2 (on Linux) do not complain. 相反,g ++ 4.8.4和5.2(在Linux上)不会抱怨。 Is this a bug in the older version of the compiler or a gray area in the standard? 这是旧版编译器中的错误还是标准中的灰色区域?


Addendum 附录

clang 3.4.1 too seems not to like it: 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

(and @Baum mit Augen in the comments reports that it still doesn't work in 3.7) (并且@Baum mit Augen在评论中报告它在3.7中仍然不起作用)

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) : 我不知道以下内容是否可以启发您,但我发现了缺陷报告941:状态为C ++ 11 的已删除功能模板的显式专业化,其内容如下: (Emphasis Mine)

According to 14.7.3 [temp.expl.spec] paragraph 1, only non-deleted function templates may be explicitly specialized. 根据14.7.3 [temp.expl.spec]段落1,只有未删除的功能模板可以显式专用。 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. 但是,似乎没有迫切需要此限制,并且在仍然允许使用显式专门化版本的情况下,禁止使用隐式实例化的专门化功能可能很有用。

Proposed resolution (February, 2010): 拟议的决议(2010年2月):

Change 14.7.3 [temp.expl.spec] paragraph 1 as follows: 将14.7.3 [temp.expl.spec]段落1更改如下:

An explicit specialization of any of the following: 下列任何一项的显式专业化:

non-deleted 未删除 function template 功能模板

class template 类模板

non-deleted 未删除 member function of a class template 类模板的成员函数

static data member of a class template 类模板的静态数据成员

member class of a class template 类模板的成员类

member class template of a class or class template 类的成员类模板或类模板

non-deleted 未删除 member function template of a class or class template 类的成员函数模板或类模板

can be declared... 可以声明...

Now the current state of the draft standard N4527 is 14.7.3 Explicit specialization [temp.expl.spec]: 现在,标准草案N4527的当前状态为14.7.3显式专业化[temp.expl.spec]:

1 An explicit specialization of any of the following: 1以下任何一项的显式专业化:

(1.1) — function template (1.1)—功能模板

(1.2) — class template (1.2)-类模板

(1.3) — variable template (1.3)-变量模板

(1.4) — member function of a class template (1.4)-类模板的成员函数

(1.5) — static data member of a class template (1.5)-类模板的静态数据成员

(1.6) — member class of a class template (1.6)-类模板的成员类

(1.7) — member enumeration of a class template (1.7)—类模板的成员枚举

(1.8) — member class template of a class or class template (1.8)-类或类模板的成员类模板

(1.9) — member function template of a class or class template (1.9)—类或类模板的成员函数模板

... ...

So I guess: 所以我猜:

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

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

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

Is C++11 standard compatible code and should be accepted. 是C ++ 11标准兼容的代码,应被接受。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 无法使用 std::enable_if 在 g++/clang++ 上编译显式专用模板结构 - Failing to compile explicitly specialized template struct on g++/clang++ with std::enable_if 编译模板类因g ++或clang ++失败 - Compile template class failed by g++ or clang++ 哪个是更专业的模板功能? clang和g ++有所不同 - Which is the more specialized template function? clang and g++ differ on that G ++,clang ++和std :: function - G++, clang++ and std::function “模拟”std :: declval问题。 g ++中的Works(种类)无法在clang ++中编译 - “Emulating” std::declval issues. Works (kind of) in g++, fails to compile in clang++ 使用clang ++和g ++,双嵌套模板类中的c ++ static int def失败 - c++ static int def in doubly nested template class fails with clang++ and g++ g ++和clang ++在模板类中定义的朋友模板函数的不同行为 - g++ and clang++ different behaviour with friend template function defined inside a template class g ++中的奇怪编译错误(clang ++可以正常编译) - Strange Compile Errors in g++ (clang++ compiles fine) 使用 std::acos 和 clang++ 而不是 g++ 的 Constexpr 编译错误 - Constexpr compile error using std::acos with clang++ not g++ 有没有办法让 G++/clang++ 的编译时间和 MSVC 一样快? - Is there a way to make G++/clang++ compile times as fast as MSVC?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM