【问题标题】:Variadic template folding program fails in gcc9可变参数模板折叠程序在 gcc9 中失败
【发布时间】:2019-07-07 15:42:08
【问题描述】:

我使用 g++ 8.3 使以下程序与 -std=c++14 和 -std=c++1z 一起按预期工作。但是,当我升级到 g++ 9.1 时,它仅在 -std=c++14 时有效,但不适用于更高版本。

#include <iostream>
using namespace std;

#if __cplusplus >= 201500L // C++17 or higher

template <typename... Args>
auto sum(Args&&... args) 
{
    return (0 + args);// + ... );
}

#elif __cplusplus >= 201402L // C++14

auto sum() { return 0; }
template <typename T>
auto sum(T&& t) { return t; }
template <typename T, typename... Rest>
auto sum(T&& t, Rest&&... r) 
{
    return t + sum(forward<Rest>(r)...);
}

#else
#error "***You need C++14 or higher to compile this program***"
#endif

int main()
{
    cout << sum() << " result of 2 + 3=>" << sum(2, 3) <<
        " result of 12+15+18=>" << sum(12, 15, 18) << "\n";
#if __cplusplus >= 201500L // C++17 or higher
    cout << "Compiled as C++17 program\n";
#else
    cout << "Compiled as C++14 program\n";
#endif
}

当我使用 -std=c++1z、c++17 或 c++2a 时,g++ 9.1 生成以下错误消息(及其同级主机):

In function 'auto sum(Args&& ...)':
error: parameter packs not expanded with '...':
   12 |     return (0 + args);// + ... );
      |            ~~~^~~~~~~
note:         'args'
In function 'int main()':
error: no match for 'operator<<' (operand types are 'std::ostream' {aka 'std::basic_ostream<char>'} and 'void') 
   32 |     cout << sum() << " result of 2 + 3=>" << sum(2, 3) <<
      |     ~~~~ ^~ ~~~~~
      |     |          |   
      |     |          void
      |     std::ostream {aka std::basic_ostream<char>}

【问题讨论】:

  • 我无法确认 g++ 8.3 错误地将其接受为 C++1z。

标签: c++ templates gcc c++17 variadic-templates


【解决方案1】:

(0 + args) 不是有效的折叠表达式。

你想要(0 + ... + args)


另外,对于我来说,GCC 8.3(带有-std=c++1zrejects 你的代码。

【讨论】:

  • 我认为重要的部分是它被接受为 g++ 8.3 的 C++1z 的断言。
  • 谢谢。通过这个建议的更正,代码可以在 g++ 9.1 中正确编译为 c++17 程序。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-06-05
  • 2012-10-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-23
相关资源
最近更新 更多