473,396 Members | 1,875 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

Implicit conversion to complex<double>

Hi

I have a array of complex numbers that are stored in a simple double
array. This is done since the array is part of an wrapper for an
external C library, and the imaginary part of the first element, and
the last element are known to be 0. I've implemented a []-operator
that returns a ComplexReference object that basically maps a
complex<doubleinto the storage used in the array.

What I would like to do is using the ComplexReference object as a
complex<doubleobject, as shown in the code below, but I can not do
this implicitly, only through the explicit cast.

Is there any way to make this work so that the ComplexReference object
will behave like a complex<doublefrom the users point of view
without wrapping all the functions associated with std::complex, using
a temporary complex<doubleobject, or using a explicit cast?

#include "complexarray.h"

#include <complex>
#include <iostream>

int main()
{
ComplexArray a(6);

// Works:
a[0] = std::complex<double>(1.0, 0.0);
a[1] = std::complex<double>(5.1, 2.0);
a[2] = std::complex<double>(2.0, 1.1);
a[3] = std::complex<double>(5.5, 0.0);

// Does not work:
std::cout << "|a[2]| = " << std::abs(a[2]) << "\n";

// Works
std::cout << "|a[2]| = " <<
std::abs(static_cast<std::complex<double(a[2])) << "\n";

// Also works
std::complex<doublec = a[2];
std::cout << "|a[2]| = " << std::abs(c) << "\n";

exit(EXIT_SUCCESS);
}
complexarray.h:

#include <complex>
#include <vector>

class ComplexReference {
public:
ComplexReference(double& re, double& im)
: re_(re), im_(im) {}

inline operator std::complex<double>() const
{
return std::complex<double>(re_, im_);
}

inline ComplexReference&
operator=(const std::complex<doublec)
{
re_ = c.real();
im_ = c.imag();
return *this;
}

private:
double& re_;
double& im_;
};

class ComplexArray {
public:
typedef ComplexReference reference;
typedef std::complex<doubleconst_reference;

// Note: n is length of data, not number of complex elements.
explicit ComplexArray(int n = 0) : data_(n), dummy(0) {}

inline const_reference operator[](size_t i) const
{
size_t n = data_.size();
if (i == 0 || (i == n/2 && n%2 == 0)) {
return const_reference(data_[i], 0);
}
return const_reference(data_[i], data_[data_.size() - i]);
}

inline reference operator[](size_t i)
{
size_t n = data_.size();
if (i == 0 || (i == n/2 && n%2 == 0)) {
return reference(data_[i], dummy);
}
return reference(data_[i], data_[data_.size() - i]);
}

inline size_t size() const
{
return data_.size() / 2 + 1;
}

private:
/// The data vector.
std::vector<doubledata_;

/// Dummy object.
double dummy;
};

--
Per Røe

Jul 12 '07 #1
1 9353
pe****@nr.no wrote:
Hi

I have a array of complex numbers that are stored in a simple double
array. This is done since the array is part of an wrapper for an
external C library, and the imaginary part of the first element, and
the last element are known to be 0. I've implemented a []-operator
that returns a ComplexReference object that basically maps a
complex<doubleinto the storage used in the array.

What I would like to do is using the ComplexReference object as a
complex<doubleobject, as shown in the code below, but I can not do
this implicitly, only through the explicit cast.

Is there any way to make this work so that the ComplexReference object
will behave like a complex<doublefrom the users point of view
without wrapping all the functions associated with std::complex, using
a temporary complex<doubleobject, or using a explicit cast?
Not really. One class can never behave just like another. For example, only
one user defined conversion may be called implicitly to match a function
argument. The problem with the functions associated with std::complex are
that they are templates. If you take std::abs, you have

double abs(double);
float abs(float);

and so on in <cmath>,
and the function you are interested in, is

template <class TT abs(const complex<T>&);

And as you have seen, the compiler will not even try this. The problem is
that T cannot be deduced.
#include "complexarray.h"

#include <complex>
#include <iostream>

int main()
{
ComplexArray a(6);

// Works:
a[0] = std::complex<double>(1.0, 0.0);
a[1] = std::complex<double>(5.1, 2.0);
a[2] = std::complex<double>(2.0, 1.1);
a[3] = std::complex<double>(5.5, 0.0);

// Does not work:
std::cout << "|a[2]| = " << std::abs(a[2]) << "\n";

// Works
std::cout << "|a[2]| = " <<
std::abs(static_cast<std::complex<double(a[2])) << "\n";
This works because both the argument for abs and its expected parameter is
on the form
std::complex<T>,
which means T can be deduced.
>
// Also works
std::complex<doublec = a[2];
std::cout << "|a[2]| = " << std::abs(c) << "\n";
//Also works:
std::cout << std::abs<double>(c);

Here, there are only one candidate, and the template parameter is selected
by hand.

//Also works
std::cout << abs(std::complex<double>(c));

This is the cast with function style syntax. At least it is shorter than
static_cast. Note that since the argument is a class from std, the compiler
will look for abs in std.
>
exit(EXIT_SUCCESS);
EXIT_SUCCESS is declared in <cstdlib>/<stdlib.h>
}
complexarray.h:

#include <complex>
#include <vector>

class ComplexReference {
public:
ComplexReference(double& re, double& im)
: re_(re), im_(im) {}

inline operator std::complex<double>() const
Note that inline is implied for functions defined inside the class
definition.
{
return std::complex<double>(re_, im_);
}

inline ComplexReference&
operator=(const std::complex<doublec)
{
re_ = c.real();
im_ = c.imag();
return *this;
}

private:
double& re_;
double& im_;
};

class ComplexArray {
public:
typedef ComplexReference reference;
typedef std::complex<doubleconst_reference;

// Note: n is length of data, not number of complex elements.
explicit ComplexArray(int n = 0) : data_(n), dummy(0) {}

inline const_reference operator[](size_t i) const
size_t should be a typedef. It is defined in <cstddef>, <cstdio>, <cstring>
and <ctime>, and unless you include one of the .h variants, you should use
std::size_t, or write using std::size_t. Here, however, the correct type
would be std::vector<double>::size_type.
{
size_t n = data_.size();
if (i == 0 || (i == n/2 && n%2 == 0)) {
return const_reference(data_[i], 0);
}
return const_reference(data_[i], data_[data_.size() - i]);
}

inline reference operator[](size_t i)
{
size_t n = data_.size();
if (i == 0 || (i == n/2 && n%2 == 0)) {
return reference(data_[i], dummy);
}
return reference(data_[i], data_[data_.size() - i]);
}

inline size_t size() const
{
return data_.size() / 2 + 1;
}

private:
/// The data vector.
std::vector<doubledata_;

/// Dummy object.
double dummy;
};
--
rbh
Jul 12 '07 #2

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Pepijn Kenter | last post by:
Dear experts. I have a vector<float> and want to convert that to a vector<double>. I optimistically tried: #include <vector> #include <iostream> using namespace std; int main() {
20
by: Anonymous | last post by:
Is there a non-brute force method of doing this? transform() looked likely but had no predefined function object. std::vector<double> src; std::vector<int> dest; ...
9
by: Greg Buchholz | last post by:
/* While writing a C++ version of the Mandelbrot benchmark over at the "The Great Computer Language Shootout"... http://shootout.alioth.debian.org/gp4/benchmark.php?test=mandelbrot&lang=all ...
2
by: mhs1pk | last post by:
Hi, I m a having problem while trying to make the return type of a method in MFC appl in VC6 as complex<double>. If i declear a variable wth std::complex<double> type, it is compled successfully....
11
by: Bo Peng | last post by:
Dear C++ experts, I need to store and retrieve a meta information that can be int or double. The program would be significantly simpler if I can handle two types uniformly. Right now, I am using...
2
by: PengYu.UT | last post by:
Hi, In FFTW (http://www.fftw.org/), it defines the funciton fftw_malloc to allocate memory properly aligned. However, I only want to use new to allocate memory for std::complex<double>. Can...
3
by: J.M. | last post by:
I have data in a double array of length 2N, which actually represents complex numbers with real and imaginary parts interlaced. In other words, elements in this array with even indices represents...
5
by: jeremit0 | last post by:
I'm trying to sort a vector<complex<double and can't figure it out. I recognize the problem is that there isn't a default operator< for complex data types. I have written my own operator and can...
3
by: huili80 | last post by:
Like in the following. Though it gives the expected result with gcc4.0, is it really safe to do that? What if it's not double but some non-POD type? -----------------------------------------...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.