首页 > c++ > 英特尔icpc和C ++ 14:如何constexpr std :: complex?

英特尔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是anotated constexpr。在GCC 5.4中它是:

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

问题

In my calculations I use the imaginary unit and I think that the compiler should be able to simplify these operations at compile time by reducing things like

a + i b --> std::complex(a,b)

Of course the above is simplified and my expressions usually look more complex (pun intended).

In C++14 I can use the complex literals for that, whereas in C++11 I was using a constexpr std::complex variable. However, both of these methods fail with the Intel C++ Compiler icpc with the error messages as comments in the source.

How can I work around these glitches?

#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;
}

Bonus question: Why is test2 optimized away and replaced by a jump to test3? (see https://godbolt.org/g/pW1JZ8)

解决方法

The error on complex literals is self-explanatory. The version of the intel compiler I got handy (16.0.3) neither supports them.

When it comes to the second error, I'd say it mostly depends on the GCC standard library version you are using, because icpc does not ship a (complete) standard library. I have installed GCC 5.4 and your test2 function compiles correctly.

What should make the difference is whether the constructor of std::complex is anotated constexpr. In GCC 5.4 it is:

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