非命名空间作用域中的显式特化不在GCC中编译

rub*_*ict 9 c++ gcc templates bug-reporting language-lawyer

以下代码在Clang中编译,但在GCC中不编译:

template<typename T>
struct Widget
{
    template<typename U>
    void foo(U)
    {
    }

    template<>
    void foo(int*)
    {
    }
};
Run Code Online (Sandbox Code Playgroud)

根据C++标准([temp.expl.spec],第2段):

可以在可以定义相应主模板的任何范围中声明显式特化

这是GCC中的一个错误,如果是这样,我怎样才能在它的bug追踪器中找到它?

这是GCC的输出:

prog.cc:13:14: error: explicit specialization in non-namespace scope 'struct Widget<T>'
     template<>
              ^
Run Code Online (Sandbox Code Playgroud)

我正在使用GCC HEAD 8.0.1 -std=c++2a.

son*_*yao 10

这应该是一个GCC错误.应该允许在任何范围内完全专业化,包括在类定义中.

根据CWG 727,[temp.expl.spec]第2段改为

(强调我的)

应在包含专用模板的命名空间中声明显式特化.其声明者id或类头名未被限定的显式特化应在模板的最近的封闭命名空间中声明,或者,如果命名空间是内联的(10.3.1 [namespace.def]),则来自其的任何命名空间封闭命名空间集.这样的声明也可以是一个定义.如果声明不是定义,则可以稍后定义专门化(10.3.1.2 [namespace.memdef]).

(强调我的)

可以在可以定义相应主模板的任何范围中声明显式特化(10.3.1.2 [namespace.memdef],12.2 [class.mem],17.6.2 [temp.mem]).

GCC似乎没有遵循这一点.

编辑

我已将此问题报告为错误85282.

  • @songyuanyao 不,不是真的。该缺陷报告已追溯应用于 C++14。 (2认同)
  • @cppBeginner我认为使用Gcc; 是的,Gcc仍然没有解决这个问题; [clang](https://wandbox.org/permlink/R3dM6pQpsNR5IWje)工作正常. (2认同)

NoS*_*tAl 9

如果有人正在寻找解决方法,直到在 gcc 中修复此问题:

可以使用std::is_same_vGodboltif constexpr

template<typename T>
struct Widget
{
    template<typename U>
    void foo(U)
    {
        if constexpr (std::is_same_v<U, int*>) {
            std::cout << "int*\n";
        }
        std::cout << "U\n";
    }

};
Run Code Online (Sandbox Code Playgroud)