【C++2.0新特性】explicit for ctors

Posted by LudoArt on September 14, 2019

explicit

explicit for ctors taking one argument

struct Complex
{
    int real, imag;
    
    Complex(int re, int im=0):real(re), imag(im) {}
    
    Complex operator+(const Complex& x)
    {
        return Complex((real + x.real), (imag + x.imag));
    }
};

Complex c1(12, 5);
Complex c2 = c1 + 5; /*5会启用隐式类型转换,调用其构造函数,成为一个Complex类型,再进行+运算*/
struct Complex
{
    int real, imag;
    
    Complex(int re, int im=0):real(re), imag(im) {}
    
    explicit
    Complex operator+(const Complex& x)
    {
        return Complex((real + x.real), (imag + x.imag));
    }
};

Complex c1(12, 5);
Complex c2 = c1 + 5; /*[Error]no match for 'operator+'(operand types are 'Complex' and 'int')*/
/*因为+的运算符重载函数加上了关键字explicit,从而不会进行上一个例子中的隐式转换*/

explicit for ctors taking more than one argument

class P
{
public:
	P(int a, int b)
	{
		cout << "P(int, int)" << endl;
	}

	explicit P(int a, int b, int c)
	{
		cout << "explicit P(int a, int b, int c)" << endl;
	}
};

void fp(const P&) {}

int main() {
	P p1(77, 55);
	P p2{ 77, 55 };
	P p3{ 77,55,66 };  /*explicit P(int a, int b, int c)*/
	/*P p4 = { 77,55,66 };  //复制列表初始化不能使用标记为“显示”的构造函数*/
	P p5(77, 55, 66);  /*explicit P(int a, int b, int c)*/
	fp({ 77, 55 });
	/*fp({ 77,55,66 });  //复制列表初始化不能使用标记为“显示”的构造函数*/
	fp(P{ 77, 55 });
	fp(P{ 77,55,66 });  /*explicit P(int a, int b, int c)*/
	return 0;
}

explicit用于类型转换

class Plebe
{
    Plebe(int);  /*automatic int-to-plebe conversion*/
    explicit Plebe(double);  /*requires explicirt use*/
};

Plebe a, b;
a = 5;  /*implicit conversion, call Plebe(5)*/
b = 0.5;  /*not allowed*/
b = Plebe(0.5);  /*explicit conversion*/
class Plebe
{
    operator int() const;
    explicit operator double() const;
};

Plebe a, b;
int n = a;  /* int-to-plebe automatic conversion*/
double x = b;  /*not allowed*/
x = double(b);  /*explicit conversion, allowed*/