I'm looking for a function that returns a reference to real or imag values of a complex number in C++11. In C++03 I could say:
complex<double> C; cin >> C.real();
But in C++11 that gives me a compile error since the C.real() returns a value not a reference.
I found out that I can write this:
double t; cin >> t; C.real(t);
but it isn't straightforward and for example if I want to multiply the real part of c by 2 and ad it by 1 I should say:
C.real(2*C.real() + 1);
That is not clean.
Is there any other [clean] way to do that?
If you really want to separate input for real and imaginary parts of a complex, you could try IO manipulators approach.
#include <complex>
#include <iosfwd>
class proxy_complex {
explicit proxy_complex(std::istream& strm, bool f)
: strm_(&strm), flag(f) { }
proxy_complex(const proxy_complex&) = default;
std::istream* strm_;
bool flag; // flag to check whether we're writing real or imag
public:
template<typename T>
std::istream& operator>>(std::complex<T>& c)
{
T n;
if (*strm_ >> n)
flag ? c.real(n) : c.imag(n);
return *strm_;
}
friend proxy_complex operator>>(std::istream& is, proxy_complex(*func)(std::istream&))
{
return func(is);
}
friend proxy_complex real(std::istream&);
friend proxy_complex imag(std::istream&);
};
inline proxy_complex real(std::istream& is)
{
return proxy_complex(is, true);
}
inline proxy_complex imag(std::istream& is)
{
return proxy_complex(is, false);
}
You can put the above code in a header file of its own (if you do that, it might be a good idea to wrap it in a namespace).
Usage:
#include <iostream>
#include "my_header.h"
int main()
{
std::complex<double> c;
std::cin >> real >> c >> imag >> c;
if (std::cin) std::cout << c;
}
Hope I guessed your definition of "clean" correctly :)
Sorry to be negative, but your question starts from a wrong premise. Concerning std::complex
the 2011 standard is backward compatible. Code of the form
complex<double> C; cin >> C.real();
was never valid C++. The 2003 standard only gives the member function
T std::complext<T>::real() const;
but not
const T& std::complext<T>::real() const; // non-standard
T& std::complext<T>::real(); // non-standard
even though some implementations (such as that shipped with gcc 4.3) may have implemented these two instead.
Now, to answer your question. Clearly, the cleanest way is to follow the intention of the standard. The 2011 standard adds the following setters
void std::complex<T>::real(T);
void std::complex<T>::imag(T);
so you can now simply use those to set the real or imaginary parts separately.
However, those cannot be used in a function taking T&
, such as operator>>
. For that you must do some nasty tricks like
template<typename T>
inline T& get_real(std::complex<T>&z) { return reinterpret_cast<T(&)[2]>(z)[0]; }
template<typename T>
inline T& get_imag(std::complex<T>&z) { return reinterpret_cast<T(&)[2]>(z)[1]; }
std::complex<double> z;
cin >> get_real(z) >> get_imag(z);
Actually, as pointed out in a comment by bames53, the standard guarantees std::complex
to be laid out such that this always works.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With