使用'new'时未初始化的std :: complex构造函数 [英] Uninitialized std::complex constructor when using 'new'

查看:155
本文介绍了使用'new'时未初始化的std :: complex构造函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在对程序进行性能分析时,我意识到10%的代码花在了一个愚蠢的 std :: complex< double>()构造函数中,并使用了新的std :: complex< double> [size_of_array]

In profiling my program I realized that 10% of the code is spent in a stupid std::complex<double>() constructor, using new std::complex<double>[size_of_array].

我已经在网上搜索了<$ c $的默认构造函数c> std :: complex 似乎将double()值当作实部和虚部。由于C ++不会初始化双数,所以我想知道为什么g ++会麻烦地用零初始化 std :: complex ,以及我是否可以通过某种方式解决整个程序( *)

I have searched through the web and the default constructor for std::complex seems to take as real and imaginary parts the values double(). Since C++ does not initialize double numbers, I wonder why g++ bothers to initialize std::complex with zeros, and whether I could work around this through the whole program in some way (*)

(*)现在,我必须对创建复数数组的函数进行特例处理,以分配未初始化的双精度数组并将其重铸为复数。

(*) right now I have to special case the functions that create arrays of complex numbers to allocate uninitialized arrays of doubles and recast them as complex.

编辑:如下所示,这是我的疏忽。默认构造函数的实部和虚部( http:// en都是空的构造函数。 cppreference.com/w/cpp/numeric/complex/complex

as pointed below, it was an oversight on my side. The default constructor has empty constructors for the real and imaginary part (http://en.cppreference.com/w/cpp/numeric/complex/complex)

 complex( const T& re = T(), const T& im = T() );

,但是规范随后介绍了double的特殊情况

but the specification then introduces special cases for double

 complex(double re = 0.0, double im = 0.0);

这种特殊情况引入了所有开销,因为它绕过了'double的实际默认构造函数。 '不会执行任何操作(与int,long,float等相同)。

It is this special case that introduces all the overhead, as it bypasses the actual default constructor of 'double' which does nothing (same as for int, long, float, etc).

推荐答案


I想知道为什么g ++会麻烦初始化带有零的std :: complex

I wonder why g++ bothers to initialize std::complex with zeros

因为标准说必须这样做,所以默认构造函数声明为:

Because the standard says it must do so, the default constructor is declared as:

constexpr complex(double re = 0.0, double im = 0.0);

因此它将两个成员都设置为零。

so it sets both the members to zero.

标准库通常会安全地初始化类型,而不是像使用 double int * ,例如 std :: vector< double> 如果您调整大小,也将其元素初始化为零,以便添加新元素。您可以通过在向量中不添加元素,直到您知道希望它们具有什么值来控制向量

It is normal for the standard library to safely initialize types, rather than leaving them uninitialized as you get with built-in types such as double and int*, for instance std::vector<double> zero-initializes its elements too if you resize it so that new elements get added. You can control this for vector by not adding elements to the vector until you know what values you want them to have.

复杂的一种可能的解决方法是使用不执行初始化的类型:

One possible workaround for complex is to use a type that doesn't do the initialization:

struct D
{
  D() noexcept { }; // does not initialize val!
  D(double d) noexcept : val(d) { }
  operator double() const noexcept { return val; }
  D& operator=(double d) noexcept { val = d; return *this; }
  double val;
};

现在,如果您使用 std :: complex< D> 默认构造函数不执行任何操作。将 explicit 添加到转换构造函数和/或转换运算符中以适合您的口味。

Now if you use std::complex<D> the default constructor does nothing. Add explicit to the converting constructor and/or the conversion operator to suit your taste.

这篇关于使用'new'时未初始化的std :: complex构造函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆