Far*_*zam 4 c++ gcc complex-numbers c++11
我正在寻找一个函数,它返回对C++ 11中复数的实数或图像值的引用.在C++ 03中,我可以说:
complex<double> C; cin >> C.real();
但是在C++ 11中,由于C.real()返回的值不是引用,因此给出了编译错误.
我发现我可以这样写:
double t; cin >> t; C.real(t);
但它并不简单,例如,如果我想将c的实部乘以2并将其加1,我应该说:
C.real(2*C.real() + 1);
那不干净.
还有其他[干净]的方法吗?
如果您真的想要为复杂的实部和虚部分开输入,可以尝试IO操纵器方法.
#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);
}
Run Code Online (Sandbox Code Playgroud)
您可以将上面的代码放在自己的头文件中(如果这样做,将它包装在命名空间中可能是个好主意).
用法:
#include <iostream>
#include "my_header.h"
int main()
{
std::complex<double> c;
std::cin >> real >> c >> imag >> c;
if (std::cin) std::cout << c;
}
Run Code Online (Sandbox Code Playgroud)
希望我猜对你正确定义"干净":)
很抱歉持否定态度,但你的问题是从错误的前提开始的。关于std::complex2011标准是向后兼容的。表格代码
complex<double> C; cin >> C.real();
Run Code Online (Sandbox Code Playgroud)
从来都不是有效的 C++。2003年标准只给出了成员函数
T std::complext<T>::real() const;
Run Code Online (Sandbox Code Playgroud)
但不是
const T& std::complext<T>::real() const; // non-standard
T& std::complext<T>::real(); // non-standard
Run Code Online (Sandbox Code Playgroud)
即使某些实现(例如 gcc 4.3 附带的实现)可能已经实现了这两个。
现在,回答你的问题。显然,最干净的方法是遵循标准的意图。2011年标准添加了以下设置器
void std::complex<T>::real(T);
void std::complex<T>::imag(T);
Run Code Online (Sandbox Code Playgroud)
所以你现在可以简单地使用它们来分别设置实部或虚部。
但是,这些不能用在采用 的函数中T&,例如operator>>。为此,你必须做一些令人讨厌的把戏,比如
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);
Run Code Online (Sandbox Code Playgroud)
实际上,正如 bames53 的评论中指出的那样,该标准保证std::complex了其始终有效。