英特尔 icpc 和 C++14:如何 constexpr std::complex?

Intel icpc and C++14: How to constexpr std::complex?

在我的计算中,我使用了虚数单位,我认为编译器应该能够在编译时通过减少像

这样的东西来简化这些操作
a + i b --> std::complex(a,b)

当然以上是简化的,我的表达通常看起来更复杂(双关语)。

在 C++14 中,我可以为此使用复杂文字,而在 C++11 中,我使用的是 constexpr std::complex 变量。但是,这两种方法在英特尔 C++ 编译器 icpc 中均失败,错误消息作为源代码中的注释。

我该如何解决这些问题?

#include <complex>

auto test1(double a, double b)
{
  // error #1909: complex integral types are not supported
  using namespace std::complex_literals;
  auto z = a + 1i*b;
  return z;
}

auto test2(double a, double b)
{
  // error: calling the default constructor for "std::complex<double>" does not produce a constant value
  constexpr std::complex<double> I(0,1);
  auto z = a + I*b;
  return z;
}

auto test3(double a, double b)
{
  // Can this be optimized as good as the others?
  std::complex<double> I(0,1);
  auto z = a + I*b;
  return z;
}

奖金问题: 为什么 test2 被优化掉并被跳转到 test3? (参见 https://godbolt.org/g/pW1JZ8

复杂文字的错误是不言自明的。我手边的intel编译器版本(16.0.3)都不支持。

关于第二个错误,我想说这主要取决于您使用的 GCC 标准库版本,因为 icpc 没有提供(完整的)标准库。我已经安装了 GCC 5.4,你的 test2 函数编译正确。

不同之处在于 std::complex 的构造函数是否被注释 constexpr。在 GCC 5.4 中是:

       _GLIBCXX_CONSTEXPR complex(const _Tp& __r = _Tp(), const _Tp& __i = _Tp())
  : _M_real(__r), _M_imag(__i) { }