6

我刚刚尝试在 Ubuntu 13.04 上使用 clang 3.3 和 GCC 4.7.3 标准库头文件编译相当大的代码体。这一切都很顺利,除了一个问题。这段代码已经在这台机器上用标准的 Ubuntu clang 3.2 包编译,所以我假设这是 clang 3.3 编译器的一些变化。与使用复杂标头的 const 和 constexpr 有关的问题。特别是复杂类型具有以下代码块

#ifdef __GXX_EXPERIMENTAL_CXX0X__
      // _GLIBCXX_RESOLVE_LIB_DEFECTS
      // DR 387. std::complex over-encapsulated.
      constexpr double
      real() { return __real__ _M_value; }

      constexpr double
      imag() { return __imag__ _M_value; }
#else
      double&
      real() { return __real__ _M_value; }

      const double&
      real() const { return __real__ _M_value; }

      double&
      imag() { return __imag__ _M_value; }

      const double&
      imag() const { return __imag__ _M_value; }
#endif

在我的编译中,我输入了第一个代码块,因此编译器看到

constexpr double real() { return __real__ _M_value; }

这会导致 clang 产生一个错误,即真正的成员函数不是 const 并具有以下内容

/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/complex:1212:7: 
note: candidate function not viable: 'this' argument has type 'const complex<double>',
      but method is not marked const

      real() { return __real__ _M_value; }

我已经阅读了以下文章`constexpr` 和 `const` 之间的区别以及其他一些类似文档,但我仍然不清楚这是 GCC 头问题还是 clang 编译器问题。我的感觉是标记为 constexpr 的成员函数应该被编译器视为 const 在这种情况下clang是错误的。

4

1 回答 1

13

根据 clang 的状态页面N3652 对 constexpr 函数的放宽要求已部分实现。这篇论文发生了很大的变化。以下段落已被删除。

非构造函数的非静态成员函数的 constexpr 说明符将该成员函数声明为 const (9.3.1)。

此更改意味着您的函数不能再在const对象上调用。此外,请参阅Fixing constexpr member functions without const,这是修复库中这些区域的建议。

于 2013-06-21T22:18:27.657 回答