在我的计算中,我使用了虚构单元,我认为编译器应该能够在编译时简化这些操作,减少像
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) { }