【c++】由构建复数类简析c++的user defined literal特性

User defined literal是c++提供的特性,可以让编程者仅用常规的几个数据类型来初始化自定义的类对象,而不需要显式调用类构造/拷贝方法,使代码可读性更高。但实际上这本质上还是是运算符的重载,还是要调用一部分方法。下文记录了尝试该特性的实验,这个小实验以构建一个复数类为契机,简单了解一下udl特性。

首先构建一个简单的复数类模板,只实现读取/赋值实部虚部的接口:

template  class ComplexBase {
public:
	ComplexBase() = default;

	T re() const {return x;}
	T& re() {return x;}
	T im() const {return y;}
	T& im() {return y;}

protected:
	T x;
	T y;
};

对该类派生出一个实虚部都是整数类型的虚数类以及相应的重载方法:

class ComplexInt : public ComplexBase {
public:
	ComplexInt() = default; // explicit declaration, avoid being ambiguous
	ComplexInt(int i, int j) { x = i; y = j; }

	/* Leave copy and = to default */

	ComplexInt(int i) { x = i; y = 0;} // converting constructor

	inline friend std::ostream& operator<< (std::ostream& os, ComplexInt c) {
		os << c.re() << " + " << c.im() << "i";
		return os;
	}
};

inline ComplexInt operator+ (const ComplexInt c1, const ComplexInt c2) {
	ComplexInt c;
	c.re() = c1.re() + c2.re();
	c.im() = c1.im() + c2.im();
	return c;
}

inline ComplexInt operator- (const ComplexInt c1, const ComplexInt c2) {
	ComplexInt c;
	c.re() = c1.re() - c2.re();
	c.im() = c1.im() - c2.im();
	return c;
}

inline ComplexInt operator* (const ComplexInt c1, const ComplexInt c2) {
	ComplexInt c;
	c.re() = c1.re() * c2.re() - c1.im() * c2.im();
	c.im() = c1.re() * c2.im() + c1.im() * c2.re();
	return c;
}

到此为止一个可以使用的复数类就实现了,在主函数里可以这样调用:

int main() {

	ComplexInt c1(1, 1), c2(1, -1);
	cout << c1 + c2 << endl;
	cout << c1 * c2 << endl;
}

但是诸如c(x, y)这样的初始化方法还是太不直观了,用户希望使用c = x + y_i这样的形式来构建简单的复数对象。

literal运算符或者说operator "",和其他类型的运算符一样,可以重载亦可模板化,甚至可以作为类的友元,其形式为

template  T2 operator "" _x();

注意!literal重载不能写在类声明内,必须置于外部。如果放在类声明内,报错:

error: literal operator 'operator""_i' must be in a namespace or global scope
        ComplexInt operator"" _i (int j) {return ComplexInt(0, j);}

其中T1只能是常用类型中的unsigned long long, long double, char, const char*这几个类型,当然还有其他类型但不常用,就不列出了。在这个复数类例子中,重载为:

ComplexInt operator"" _i (unsigned long long j) {return ComplexInt(0, j);}

该重载将一个代下表的整数转换成一个ComplexInt类的纯虚数。

通过原本就实现的类型转换,可以实现将一个整数转换成ComplexInt类的纯实数。于是可以在主函数里调用:

int main() {

	ComplexInt c1 = 1 + 1_i, c2 = 1 - 1_i;
	cout << c1 + c2 << endl;
	cout << c1 - c2 + 1 << endl;
	cout << c1 * c2 << endl;
	cout << c1 * c2 - 2_i << endl;
}

输出:

2 + 0i
1 + 2i
2 + 0i
2 + -2i
如有错误请指正,我什么都会做的

你可能感兴趣的:(学习记录,c,user-defined,literal,虚数类)