【问题标题】:std::complex initilalisation issuestd::complex 初始化问题
【发布时间】:2016-11-24 12:03:26
【问题描述】:

考虑下面的代码

#include <complex>
#include <iostream>

int main(int argc, char **argv)
{
    std::complex<double> a = 1+1i;
    std::cout<<"a ="<<a<<"\n";
    return 0;
}

当我使用 Apple LLVM 版本 8.0.0 (clang-800.0.42.1) 进行编译时,我得到的输出是

a =(1,0)

谁能解释为什么虚部被初始化为零?

【问题讨论】:

  • 似乎工作正常:ideone.com/Qa7698 您是否忘记重新编译?
  • 我使用的是 Apple LLVM 版本 8.0.0 (clang-800.0.42.1)。不是 g++!。我会编辑帖子
  • 添加 using 声明 using namespace std::literals::complex_literals; 时会发生什么?
  • Repro: melpon.org/wandbox/permlink/QBES5VmGeMrfvZoT GCC 扩展和 C++ 复杂文字之间可能存在一些不兼容。我猜 GCC 扩展可以转换为双精度(实部),所以 1+1i 被转换为双精度,然后该结果用于初始化 std::complex。

标签: c++ std complextype


【解决方案1】:

1 + 1i 正在使用 (GCC) 扩展,它创建与 C99 的 _Complex int 类型相似/等效的类型。该类型可以转换为像intdouble 这样的真实类型。 std::complex_Complex 不兼容,它没有任何构造函数来从 _Complex (*) 创建 std::complex。但是std::complex&lt;T&gt; 确实有一个采用T 的构造函数。这会触发上述转换_Complex -> T -> std::complex&lt;T&gt;

所以OP中的代码相当于:

#include <complex>
#include <iostream>

int main()
{
    double d = 1+1i;
    std::complex<double> a = d;
    std::cout<<"a ="<<a<<"\n";
    return 0;
}

1 + 1i 的虚部在转换为double 时被删除。


为防止出现此类意外,请尝试使用警告和-pedantic 进行编译。这个示例似乎是 clang 实际上添加带有 -pedantic 标志的附加警告的少数几个地方之一(对于 gcc,-pedantic 在许多情况下会更改警告输出):

prog.cc:6:19: 警告:虚常量是 GNU 扩展 [-Wgnu-imaginary-constant]
    双 d = 1+1i;

(*) IIRC,std::complex 是在 C++98 中引入的,而 _Complex 是在 C99 中引入的。

【讨论】:

  • GCC 可以添加 std::complex::complex(_Complex) 以实现互操作性。这将是相当安全的,因为它似乎不会在 C++ 类型之间添加新的转换序列。
猜你喜欢
  • 2015-02-02
  • 1970-01-01
  • 1970-01-01
  • 2015-01-22
  • 2013-03-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多