模板类中部分专用的模板 static constexpr

Bip*_*olo 7 c++ templates metaprogramming

(一个玩具,最小的不起作用的例子)

下面的代码无法使用 cpp20/17 进行编译:

template<typename TSomeTemplate>
struct A
{
    static constexpr size_t B = 1;

    template<typename T, typename... Ts>
    static constexpr size_t C = 4;

    template<typename T>
    static constexpr size_t C<T> = B;
};

int main()
{
    A<int>::C<int>;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

对于结构中的最后一行,出现“表达式未求值为常量”的错误。但是,它确实以完全专业化的方式进行编译,或者不引用 B:

template<typename TSomeTemplate>
struct Works
{
    static constexpr size_t B = 1;

    template<typename T, typename... Ts>
    static constexpr size_t C = 4;

    template<>
    static constexpr size_t C<int> = B;
};

template<typename TSomeTemplate>
struct AlsoWorks
{
    static constexpr size_t B = 1;

    template<typename T, typename... Ts>
    static constexpr size_t C = 4;

    template<typename T>
    static constexpr size_t C<T> = 2;
};
Run Code Online (Sandbox Code Playgroud)

为什么会这样呢?我怎样才能使第一个结构工作?

use*_*570 2

GCC 和 MSVC 拒绝该代码是错误的,因为该程序是格式良好的。

B是一个常量表达式,在其部分特化过程中初始化时可以用作初始值设定项C。这是一个 msvc bug,此处报告为:

使用 constexpr 静态数据成员作为初始值设定项时,MSVC 拒绝有效代码


此外,我们可以提供部分专业化C(就像您所做的那样)。这是一个 gcc 错误,报告如下:

GCC 拒绝涉及变量 template 的部分特化的有效代码