首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >gcc与clang在部分专业化中的变异参数加同类型额外参数的行为

gcc与clang在部分专业化中的变异参数加同类型额外参数的行为
EN

Stack Overflow用户
提问于 2016-03-29 19:10:07
回答 2查看 402关注 0票数 9

以下代码:

代码语言:javascript
运行
复制
#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;
}

由于以下原因,...does没有使用g++ (版本5.1.05.3.0)进行编译:

错误:部分专门化并不比主模板更专门化,因为它用包展开替换多个参数。

...but使用clang进行编译。

是否允许宣布这种局部的专门化?

附带注意:实际上,专门化是危险的,因为A<0, int>无法使用这两个编译器进行编译(模板参数的错误数量)。

EN

Stack Overflow用户

回答已采纳

发布于 2016-03-29 19:33:04

gcc是对的,代码是错误的,因为专业并不是更专业化.

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

在类模板部分专门化的参数列表中,适用以下限制:专业化应比主模板更专业化(14.5.5.2)。

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

代码语言:javascript
运行
复制
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

然后遍历偏序规则。这又涉及到为每个模板参数合成新的类型/值,并查看演绎是否可以在任何方向上成功。

当然,专门化的演绎在主用户中失败(由于N0)。在另一个方向,从temp.deduct.partial

如果从函数参数包转换了A,而P不是参数包,则类型推断失败。

由于我们试图从一个包中推断出T first,推论也会在这个方向上失败。这意味着合成的函数模板中没有一个比其他模板更专业化,这反过来意味着类模板专门化并不比主模板更专业化。因此,gcc拒绝的说法是正确的。

票数 9
EN
查看全部 2 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36293088

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档