gpt4 book ai didi

c++ - typeid(复杂(0.0,1.0)) != typeid(1.0i)

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:44:55 26 4
gpt4 key购买 nike

使用 gcc 4.9 我发现用字面量为复数生成的类型与通过常规方法创建的类型不同,即:

typeid(complex<double>(0.0,1.0)) != typeid(1.0i)
  1. 我在这里犯错了吗?
  2. 这是编译器错误还是预期的标准行为?
  3. 如果是预期的标准行为:背后的基本原理是什么?

添加缺失的 MCVE

#include <complex>
using std::complex;
using namespace std::literals::complex_literals;

#include <iostream>
using std::cout;
using std::endl;

#include <typeinfo>

int main(int argc, char* argv[]) {
if (typeid(complex<double>(0.0, 1.0)) == typeid(1.0i))
cout << "types are same as expected" << endl;
else
cout << "types are unexpectedly not the same" << endl;

cout << 1.0i*1.0i << endl;
cout << complex<double>(0.0, 1.0)*complex<double>(0.0, 1.0) << endl;
}

编译说明:

g++ -std=gnu++14 complex.cpp -o complex.exe

输出:

types are unexpectedly not the same
1
(-1,0)

有趣的是,字面量看起来甚至都不是真虚数。 (我确定我忽略了一些东西......)

最佳答案

程序的行为取决于 gcc 的语言标准模式:

有一个gcc extension for a built-in literal suffix i 产生 C99 复数。这些是不同的内置类型,例如 _Complex double ,而不是“用户定义”类(模板特化)std::complex<double>在 C++ 中使用。

在 C++14 中,C++ 现在有一个用户定义 文字后缀 i对于复数。即一个函数complex<double> operator"" i(long double)std::literals::complex_literals 内内联命名空间。

这两个字面后缀相互竞争:

  • 在 C++11 模式下,只有内置扩展是可能的,但它扩展。因此,gcc 只允许在 -std=gnu++11 中使用它模式,甚至会警告您。奇怪的是,即使在 -std=c++11 中,clang 也允许它模式。

  • strict C++14 模式(-std=c++14-std=c++1y)中,必须禁用内置扩展以消除歧义(据我所知),因此 gcc 和 clang 都选择了用户定义的文字后缀。

  • 在 gnu-extension-C++14 模式下 -std=gnu++14 , gcc 选择内置后缀(为了向后兼容?),而 clang 选择用户定义的后缀。这看起来很奇怪,我建议您在此处查找或提交错误报告。

根据选择的文字后缀,您可以得到内置类型 _Complex double或一些 std::complex<double> .

关于c++ - typeid(复杂<double>(0.0,1.0)) != typeid(1.0i),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40854253/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com