ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

c – 我可以扩展参数包并用它定义参数列表吗?

2019-10-01 18:05:03  阅读:244  来源: 互联网

标签:c language-lawyer variadic-templates clang gcc


[temp.variadic](工作草案)开始,在我看来,可以在定义另一个模板类或函数的参数列表时扩展参数包.

考虑以下课程:

template<typename... T>
struct S {
    template<T... I>
    void m() {}
};

int main() {
    S<int, char> s;
    // ...
}

目的是捕获用于专门化模板类S的类型,并使用它们为成员方法m定义非类型参数的参数列表(当然,T仅限于几种类型,但这不是问题的论点).

这是合法代码吗?我可以按照我使用的方式使用参数包吗?或者我是否误解了标准(确实确实如此)?

为了在问题中添加更多细节,以下是主要编译器的一些实验的一些结果:

> s.m< 0,'c'>():clang v3.9编译它,GCC v6.2GCC v7返回错误.
> s.m< 0>();: clang v3.9编译它,GCC v6.2返回错误,GCC v7用ICE停止编译.
> s.m<>();: clang v3.9,GCC v6.2GCC v7编译它没有错误.

至少,编译器似乎和我一样困惑.

解决方法:

模板S的定义和S< int,char>的实例化是有效的.

参见[temp.param] / 15:“模板参数包是一个参数声明,其类型包含一个或多个未展开的参数包,是包扩展.”

这意味着模板< T ... I>可以表示两种不同的东西之一:如果T是非包装类型,则它声明一个正常的参数包,接受任意数量的Ts.但是,如果T包含未扩展的参数包,则在实例化外部模板时,参数声明将扩展为一系列参数.

你第一次打电话给m是有效的,但你对m的第二次和第三次打电话是不正确的

S< int,char>的实例化看起来像这样:

template<>
struct S<int, char> {
  template<int I$0, char I$1>
  void m() {}
};

(其中我0美元和1美元是我的第一和第二片).

因此(因为对于m的调用都不能推断出I $0和I $1),s.m< 0,'c'>()是有效的但是s.m< 0>()和s.m<> ()是不正确的.

标签:c,language-lawyer,variadic-templates,clang,gcc
来源: https://codeday.me/bug/20191001/1839332.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有