typeid(complex< double>(0.0,1.0))!= typeid(1.0i) [英] typeid(complex<double>(0.0,1.0)) != typeid(1.0i)
问题描述
使用 gcc 4.9
我发现使用类型字面量为复数生成的类型与通过常规方法创建的类型不同,即:
typeid(complex< double>(0.0,1.0))!= typeid(1.0i)
$
添加缺少的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 < 类型与预期相同<< endl;
else
cout<< 类型意外不同<< endl;
cout<< 1.0i * 1.0i < endl;
cout<<复合双(0.0,1.0)*复合双(0.0,1.0)< endl;
}
编译说明:
g ++ -std = gnu ++ 14 complex.cpp -o complex.exe
输出:
类型意外不一样
1
,0)
有趣的是,文字甚至不是一个适当的虚数。 (我相信我忽略了某些东西...)
程序的行为取决于语言标准模式:
有一个 gcc扩展,用于生成 C99复数的内置文字后缀 i
。这些是内置类型,例如 _Complex double
,而不是用户定义类(模板专用化)
在C ++ 14中,C ++现在有一个用户定义的复杂数字的后缀 这两个字面后缀是竞争: 在C ++ 11模式下,是可能的,但是扩展名。因此,gcc只允许在 em> strict C ++ 14模式( 在gnu-extension-C ++ 14模式 根据哪个字面值后缀选择,你可以得到内置的 Using
Adding the missing MCVE Compile instructions: Output: Interestingly the literal does not even seem to be a proper imaginary number. (I am sure I am overlooking something...) The behaviour of the program depends on the language standard mode of gcc: There is a gcc extension for a built-in literal suffix In C++14, C++ now has a user-defined literal suffix Those two literal suffixes are competing: In C++11 mode, only the built-in extension is possible, but it is an extension. Hence, gcc only allows it in In strict C++14 mode ( In the gnu-extension-C++14 mode Depending on which literal suffix is chosen, you either get the built-in type 这篇关于typeid(complex< double>(0.0,1.0))!= typeid(1.0i)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋! i
。也就是说,函数 complex< double>
$ b中的 std :: literals :: complex_literals
内部命名空间中的运算符 $ b
-std = gnu ++ 11
模式,甚至警告你。奇怪的是,clang甚至在 -std = c ++ 11
模式下也允许它。
-std = c ++ 14
或 -std = c ++ 1y
),内置的扩展必须禁用以消除歧义(就我所知),因此gcc和clang选择用户定义的文字后缀。
-std = gnu ++ 14
中,gcc选择内置后缀兼容性?),而clang选择用户定义的后缀。这看起来很奇怪,我建议在这里寻找或提交错误报告。
_Complex double
或一些 std :: complex< double>
p> gcc 4.9
I found that types generated with type literal for complex numbers are not the same as when created by conventional means, i.e.:typeid(complex<double>(0.0,1.0)) != typeid(1.0i)
#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)
i
that produces C99 complex numbers. Those are distinct built-in types like _Complex double
, as opposed to the "user-defined" class (template specialization) std::complex<double>
used in C++.i
for complex numbers. That is, a function complex<double> operator"" i(long double)
within the std::literals::complex_literals
inline namespace.
-std=gnu++11
mode and even warns you about it. Strangely enough, clang allows it even in -std=c++11
mode.-std=c++14
or -std=c++1y
), the built-in extension must be disabled to remove ambiguity (as far as I can tell), hence both gcc and clang selecting the user-defined literal suffix.-std=gnu++14
, gcc chooses the built-in suffix (for backwards-compatibility?), whereas clang chooses the user-defined suffix. This looks strange, and I'd suggest looking for or filing bug reports here._Complex double
or some std::complex<double>
.