LLVM STLExtras 中的错误:GCC11 的“const”之前预期有不合格的 id

fun*_*run 0 c++ gcc constructor class llvm

我刚刚将编译器升级到 GCC 11.1.0,但在尝试编译使用 LLVM 的程序时遇到了麻烦。

\n

发生的错误如下:

\n
In file included from /usr/include/llvm/IR/DebugInfo.h:19,\n                 from /home/<redacted>/src/sword/format/llvm.hpp:12,\n                 from /home/<redacted>/src/main.cpp:9:\n/usr/include/llvm/ADT/STLExtras.h:1793:18: error: expected unqualified-id before \xe2\x80\x98const\xe2\x80\x99\n 1793 |   result_pair<R>(const result_pair<R> &Other)\n      |                  ^~~~~\n/usr/include/llvm/ADT/STLExtras.h:1793:18: error: expected \xe2\x80\x98)\xe2\x80\x99 before \xe2\x80\x98const\xe2\x80\x99\n 1793 |   result_pair<R>(const result_pair<R> &Other)\n      |                 ~^~~~~\n      |                  )\n/usr/include/llvm/ADT/STLExtras.h:1843:22: error: expected unqualified-id before \xe2\x80\x98const\xe2\x80\x99\n 1843 |   enumerator_iter<R>(const enumerator_iter<R> &Other) : Result(Other.Result) {}\n      |                      ^~~~~\n/usr/include/llvm/ADT/STLExtras.h:1843:22: error: expected \xe2\x80\x98)\xe2\x80\x99 before \xe2\x80\x98const\xe2\x80\x99\n 1843 |   enumerator_iter<R>(const enumerator_iter<R> &Other) : Result(Other.Result) {}\n      |                     ~^~~~~\n      |                      )\n\n
Run Code Online (Sandbox Code Playgroud)\n

我查看了源代码,但不确定 LLVM 的代码是否格式错误,或者是 GCC 错误。

\n

STLExtra.h 中第 1793 行的错误与类的定义有关:

\n
template <typename R> struct result_pair {\n  ...\n  result_pair<R>(const result_pair<R> &Other)\n      : Index(Other.Index), Iter(Other.Iter) {}\n  ...\n};\n
Run Code Online (Sandbox Code Playgroud)\n

通常,当我定义带有模板参数的类时,我不会将模板参数放在构造函数的声明中(即result_pair(...))。\n事实上,当我将构造函数从 修改为 时,我的程序编译得很好result_pair<R>(...)result_pair(...)对 也做了同样的事情enumerator_iter) 。

\n

那么,LLVM的代码是错误的而GCC是正确的吗?或者这是 GCC 回归?我对 C++ 标准的了解太有限,无法有效地通过 Google 检查这是否是一个已知的错误...非常感谢任何帮助。

\n

另外,我尝试使用 clang-11 编译我的程序,但它根本无法编译,因为 C++20 功能还不存在(具体来说,它在模板中的某个地方失败了)。所以,我无法通过这种方式缩小罪魁祸首的范围。

\n

PS 由于修改后编译得很好,我想我现在就保留修改的标头。

\n

N. *_*ead 7

您提到您正在使用 C++20。从 C++20 开始,这确实是一个错误:构造函数使用 simple-template-ids 被认为容易出错且多余,因此被删除。请参阅[diff.cpp17.class]/2

正如您所提到的,您可以通过使用注入的类名来修复错误:

template <typename R>
struct result_pair {
  // ...
  result_pair(const result_pair &Other)
      : Index(Other.Index), Iter(Other.Iter) {}
  // ...
};
Run Code Online (Sandbox Code Playgroud)

特别是,这可以防止在构造函数声明中意外使用错误的模板参数,这显然不应该编译。