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 << "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:的语言标准模式
内置文字后缀i
的gcc扩展产生C99复数。与C++中使用的"用户定义"类(模板专用化)std::complex<double>
不同,它们是类似_Complex double
的独特的内置类型。
在C++14中,C++现在有一个用户定义的复数文字后缀i
。也就是说,std::literals::complex_literals
内联命名空间中的函数complex<double> operator"" i(long double)
。
这两个文字后缀相互竞争:
-
在C++11模式中,只有内置扩展是可能的,但它是的扩展。因此,gcc只在
-std=gnu++11
模式下允许它,甚至会警告你。奇怪的是,clang甚至在-std=c++11
模式下也允许它。 -
在strictC++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模板值转换为联合不可接受的转换
- 使用typeid警告未使用的变量
- 如何在 lambda 中访问捕获的此指针的"typeid"?
- Visual Studio 2017 C++,不能使用 typeid() 获取信息对象,缺少指针?;
- 为什么'typeid(x) == typeid(y)'的计算结果为 true,其中 'x' 和 'y' 分别是 T 和 T& 类型的 id-表达式?
- typeid 给出类型 m、j 和 Pj
- 在C++17中有typeid的反函数吗
- 如何实现构造函数,使其仅接受使用 typeid 的输入迭代器?
- typeid.name 返回派生类类型之前的数字
- 比较函数模板中的 VARTYPE 和 typeid().name / typename
- 返回别名标识符,而不是typeid(SOME_TYPE).name()中的类型
- typeid( " " ) != typeid(const char*)
- 将typeID转换为静态成员访问(C )的命名空间
- typeid 运算符忽略 cv 限定符背后的理由是什么?
- 为什么typeID().名称(),c 在输出中未显示const
- 当我将对象添加到向量时,为什么typeID名称会更改
- 汇编TypeID(OBJ)时会发生什么-C
- typeID检查有效后,使用reinterpret_cast
- 了解C 中的地图和向量的TypeId.name()输出
- typeid(complex<double>(0.0,1.0)) != typeid(1.0i)