我一直被教导

1. Class c(arg);


2. Class c = arg;

是两个完全等效的语句,但请看这种情况。
#include <iostream>

class Intermediary {
};

class Left {
  public:
    Left(const Intermediary &) {
        std::cout << __PRETTY_FUNCTION__ << std::endl;
    }
};

class Right {
  public:
    // The argument is there just so that the example can work, see below
    Right(int) {
        std::cout << __PRETTY_FUNCTION__  << std::endl;
    }

    operator Intermediary () const {
        std::cout << __PRETTY_FUNCTION__  << std::endl;

        return Intermediary();
    }
};

现在,如果我这样做:
Left l = Right(0);

编译器会抱怨
error: conversion from Right to non-scalar type Left requested

但是,如果我这样做:
Left l(Right(0));

然后一切都编译了,输出是
Right::Right(int)
Right::operator Intermediary() const
Left::Left(const Intermediary&)

但是,如果我这样做:
Left l = (Intermediary)Right(0);

然后一切都重新编译,输出就像上面的输出一样。

所以很明显
1. Class c(arg);


2. Class c = arg;

是不一样的,但为什么不一样,又有什么区别呢?我在网上找不到任何东西。

最佳答案



事实证明,它们并不等效。第一个从Class c构造arg,而第二个从Class构造arg,然后从Class c复制构造Right。请注意,允许实现删除该副本,通常也是如此。

Left l = Right(0);

这需要从IntermediaryIntermediary的转换,以及从Left到ojit_code的转换。标准不允许这两个连续的用户定义的转换,您必须使用以下方法至少显式地进行其中之一:
Left l = (Intermediary)Right(0);

10-08 09:33