gpt4 book ai didi

c++ - gcc vs clang 在具有可变参数和相同类型的额外参数的部分特化上的行为

转载 作者:可可西里 更新时间:2023-11-01 17:44:50 27 4
gpt4 key购买 nike

以下代码:

#include <cstddef>

template <size_t N,
typename T,
T first,
T... rest>
struct A {
};

template<typename T,
T... args>
struct A<0, T, args...> {
};

int main () {
A<0, int, 1> a0;
A<2, int, 1, 2> a2;
return 0;
}

...不编译 g++ (版本 5.1.05.3.0)由于:

error: partial specialization is not more specialized than the primary template because it replaces multiple parameters with a pack expansion

...但使用 clang 编译.

是否允许声明这样的部分特化?

旁注:实际上,自 A<0, int> 以来,特化是危险的两个编译器都无法编译(模板参数数量错误)。

最佳答案

gcc 是正确的,代码格式错误,因为特化实际上并没有更特化。


来自 [temp.class.spec] 的规则是(作为 DR 1495 的结果,链接的 h/t T.C.):

Within the argument list of a class template partial specialization, the following restrictions apply: [...] The specialization shall be more specialized than the primary template (14.5.5.2).

为了确定这一点,我们将两者重写为合成函数模板:

template <size_t N, class T, T first, T... rest>
void __f(A<N, T, first, rest...> ); // primary

template <class T, T... args>
void __f(A<0, T, args...> ); // specialization

然后通过部分排序规则。反过来,这涉及为每个模板参数合成新类型/值,并查看推导是否可以在任一方向上成功。

毫无疑问,特化的推导失败了(由于 N vs 0)。在另一个方向,来自 [temp.deduct.partial]:

If A was transformed from a function parameter pack and P is not a parameter pack, type deduction fails.

因为我们试图针对一个包推导T first,推导在这个方向上也是失败的。这意味着合成函数模板都不比其他模板更特化,这反过来意味着类模板特化并不比主模板更特化。因此,gcc 拒绝是正确的。

关于c++ - gcc vs clang 在具有可变参数和相同类型的额外参数的部分特化上的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36293088/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com