c++20 具有概念和可变参数模板参数的部分类专业化

问题描述 投票:0回答:1

希望了解为什么下面的代码会产生以下结果:

类模板部分特化并不比主模板更特化

template <typename T, std::integral... Us>
struct foo : std::false_type {};

template <std::integral T, std::integral... Us>
struct foo<T, Us...> : std::true_type {};

显然,它基于第一个模板参数更加专业,无论剩余的可变参数是否通过

std::integral
概念受到限制。

版本 2 - 对可变参数没有限制

事实上,如果我们从

Us
中删除限制,专业化就会按预期发生:

template <typename T, typename... Us>
struct foo : std::false_type {};

template <std::integral T, typename... Us>
struct foo<T, Us...> : std::true_type {};

版本 3 - 带约束的单个参数

如果我们使用单个

U
,即使存在约束,情况也是如此:

template <typename T, std::integral U>
struct foo : std::false_type {};

template <std::integral T, std::integral U>
struct foo<T, U> : std::true_type {};

版本 4 - 解决方法

我找到了一种在功能上与相关代码等效的解决方法:

template <typename T, std::integral... Us>
struct foo : std::false_type {};

template <std::integral T>
struct foo<T> : std::true_type {};

template <std::integral T, std::integral U, std::integral... Us>
struct foo<T, U, Us...> : std::true_type {};

godbolt 链接用于使用上面的代码进行实验:https://godbolt.org/z/9Tn1KeKnK

这是一个错误吗?

c++ c++20 variadic-templates c++-concepts c++-templates
1个回答
0
投票

您遇到了一个编译器错误,令人惊讶的是 GCC 和 clang 都有这个错误。相关的写法是这样的:

D1
至少与
D2
一样受约束,并且
D1
至少不与
D2
一样受约束时,声明
D2
比另一个声明
D1
受到更多约束。

- [temp.constr.order] 更多约束

此外,[temp.func.order] p6.4 指出:

否则,如果一个模板比另一个模板“更受约束”,则受更多约束的模板比另一个模板更专业。

完整的定义有些复杂,但显然,具有约束
std::integral<T>

使得部分特化比主模板受到更多约束,而主模板没有这样的约束。 更正式地说,主模板约束的析取范式为:


std::integral<U1> && std::integral<U2> && ...
部分专业化约束的析取范式为:

std::integral<T> && std::integral<U1> && std::integral<U2> && ...
后一个DNF是前一个DNF加上一个附加约束,因此,后者
包含

前者。 部分专业化受到更多限制,因此更加专业化。 编译器错误

请注意,MSVC 可以正常编译版本 1,这是理所应当的。请参阅

编译器资源管理器

。只有 GCC 和 clang 无法编译。 您的解决方法(版本 2 到 3)都不是必要的。

© www.soinside.com 2019 - 2024. All rights reserved.