C++ typeid(复数<;双精度>;(0.0,1.0))!=类型ID(1.0i)

C++ typeid(复数<;双精度>;(0.0,1.0))!=类型ID(1.0i),c++,c++11,complex-numbers,user-defined-literals,C++,C++11,Complex Numbers,User Defined Literals,使用GCC4.9我发现,用复数的type literal生成的类型与用常规方法创建的类型不同,即: typeid(complex<double>(0.0,1.0)) != typeid(1.0i) 输出: types are unexpectedly not the same 1 (-1,0) 有趣的是,文字似乎并不是一个正确的虚数。(我确信我忽略了一些东西…程序的行为取决于gcc的语言标准模式: 有一种方法可以产生C99复数。不同的是:强>内置的类型,如复杂的双,与“用户定义”

使用GCC4.9我发现,用复数的type literal生成的类型与用常规方法创建的类型不同,即:

typeid(complex<double>(0.0,1.0)) != typeid(1.0i)
输出:

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

有趣的是,文字似乎并不是一个正确的虚数。(我确信我忽略了一些东西…

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

有一种方法可以产生C99复数。不同的是:强>内置的<强>类型,如<代码>复杂的双,与“用户定义”类(模板特化)<代码> STD::C++中使用的复合< /代码>相反。

<>在C++ 14中,C++现在有一个用户定义的复数字后缀<代码> i>代码>。即,
std::literals::complex_literals
内联命名空间中的函数
complex运算符“i(长双精度)

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

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

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

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


根据选择的文字后缀,您可以获得内置类型
\u Complex double
或一些
std::Complex

您是否有可能将其放入实际编译的源代码列表中?我认为您使用的是
std::complex
,它不同于
\u complex
,它是虚常数的gnu扩展,但没有MCVE,很难说出您实际在做什么。谢谢您的更新。是的,它们是不同类型的。一个来自标准库,另一个来自编译器扩展@在C++14中,
i
是(也是?)一个文字后缀。在C++11模式下,gcc可能使用@WhozCraig clang++,在C++11模式下接受带有gnu++11扩展的程序可能是一个错误。O@dyp当我亲眼看到时,我不得不加倍努力。我的MacOSXClang3.5参考也做了同样的事情,但至少给了你一个警告,让你知道它是gnu的扩展。非常好的答案。我一直忘了用户定义的文字是在保护伞下的。
g++ -std=gnu++14 complex.cpp -o complex.exe
types are unexpectedly not the same
1
(-1,0)