繁体   English   中英

模板 class 中的部分特化模板 static constexpr

[英]Partially specialized template static constexpr in template class

(一个玩具,最小的不工作示例)

下一个代码不能用 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;
}

关于结构中的最后一行,出现“表达式未计算为常量”的错误。 但是,它确实以完全专业化或不引用 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;
};

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

你不能这样专攻,你可以使用 SFINAE 或者你可以尝试类似的东西:

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

    template<typename T, typename... Ts>
    static constexpr size_t C = sizeof...(Ts) == 0 ? B : 4;
};

我能够通过添加模板关键字来编译您的代码。

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>::template C<int>;

    return 0;
}

正如这里所引用的。

类似地,在模板定义中,不是当前实例化成员的依赖名称不被视为模板名称,除非使用了消歧关键字 template 或除非它已被建立为模板名称:

我看不出代码有什么问题。

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

这是C变量模板的部分特化,在 class scope 内部也是允许的。 它也比主模板更专业。

B显然是一个常量表达式,因为它之前已被定义为constexpr变量。 即使它仅被声明为const ,它仍然可以在常量表达式中使用(因为它是整数类型)。 编译器将其拒绝为不是常量表达式是错误的。

似乎这里只有一些编译器错误在起作用(GCC 似乎不喜欢 class scope 中的变量模板部分特化,MSVC 似乎对B的 constness 有问题。Z9375884CF4ED31C834A626C32 不抱怨)

GCC 和 MSVC 拒绝代码是错误的,因为程序格式正确。

B是一个常量表达式,可以在C的部分特化期间用作初始化器。 这是一个 msvc 错误,此处报告为:

使用 constexpr static 数据成员作为初始化程序时,MSVC 拒绝有效代码


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

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

暂无
暂无

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM