ICode9

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

c – gcc可以编译一个可变参数模板,而clang则不能

2019-09-25 18:07:16  阅读:256  来源: 互联网

标签:c c11 templates clang gcc


我正在阅读Leor Zolman先生提出的一些名为An Overview of C++11 and C++14的幻灯片.在第35页,他介绍了一种使用decltype进行求和运算的方法.

struct Sum {
  template <typename T>
  static T sum(T n) {
    return n;
  }
  template <typename T, typename... Args>
  /// static T sum(T n, Args... rest) {
  static auto sum(T n, Args... rest) -> decltype(n + sum(rest...)) {
    return n + sum(rest...);
  }
};

当使用这个片段forSum :: sum(1,2.3,4,5)时; clang-3.6(来自svn)无法使用-std = c 11 / -std = c 1y编译它,但gcc-4.9成功.当然没有返回类型的类型推导都是编译,但是涉及类型转换并且无法获得预期的结果.

那么这是否表示一个铿锵声,或者是因为gcc扩展(关于c 11或c 14)?

解决方法:

Clang的行为是正确的.这是一个GCC错误(并且演示文稿中的声明也不正确). §3.3.2[basic.scope.pdecl] / p1,6:

1 The point of declaration for a name is immediately after its
complete declarator (Clause 8) and before its initializer (if any),
except as noted below.

6 After the point of declaration of a class member, the member name can
be looked up in the scope of its class.

§3.3.7[basic.scope.class] / p1说

The following rules describe the scope of names declared in classes.

1) The potential scope of a name declared in a class consists not only
of the declarative region following the name’s point of declaration,
but also of all function bodies, default arguments,
exception-specifications, and brace-or-equal-initializers of
non-static data members in that class (including such things in nested
classes).

trailing-return-types不在该列表中.

尾部返回类型是声明符的一部分(§8[dcl.decl] / p4):

declarator:
    ptr-declarator
    noptr-declarator parameters-and-qualifiers trailing-return-type

因此,sum的可变版本不在其自己的trailing-return-type范围内,并且无法通过名称查找找到.

在C 14中,只需使用实际的返回类型推导(并省略尾随返回类型).在C 11中,您可以使用类模板和简单转发的函数模板:

template<class T, class... Args>
struct Sum {
    static auto sum(T n, Args... rest) -> decltype(n + Sum<Args...>::sum(rest...)) {
        return n + Sum<Args...>::sum(rest...);
    }
};

template<class T>
struct Sum<T>{
    static T sum(T n) { return n; }
};

template<class T, class... Args>
auto sum(T n, Args... rest) -> decltype(Sum<T, Args...>::sum(n, rest...)){
    return Sum<T, Args...>::sum(n, rest...);
}

标签:c,c11,templates,clang,gcc
来源: https://codeday.me/bug/20190925/1816349.html

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

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

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

ICode9版权所有