类实例化语法

Fab*_* A. 2 c++ standards constructor instantiation parentheses

我一直都被教导过

1. Class c(arg);
Run Code Online (Sandbox Code Playgroud)

2. Class c = arg;
Run Code Online (Sandbox Code Playgroud)

是两个完全相同的陈述,但看看这种情况.

#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();    
    }
};
Run Code Online (Sandbox Code Playgroud)

现在,如果我这样做:

Left l = Right(0);
Run Code Online (Sandbox Code Playgroud)

编译器会抱怨

error: conversion from Right to non-scalar type Left requested
Run Code Online (Sandbox Code Playgroud)

但如果我这样做:

Left l(Right(0)); 
Run Code Online (Sandbox Code Playgroud)

然后一切都编译,输出就是

Right::Right(int)
Right::operator Intermediary() const
Left::Left(const Intermediary&)
Run Code Online (Sandbox Code Playgroud)

但是,如果我这样做:

Left l = (Intermediary)Right(0);
Run Code Online (Sandbox Code Playgroud)

然后一切都再次编译,输出就像上面那样.

很明显

1. Class c(arg);
Run Code Online (Sandbox Code Playgroud)

2. Class c = arg;
Run Code Online (Sandbox Code Playgroud)

不一样,但为什么不,有什么区别?我在网上找不到任何相关信息.

K-b*_*llo 5

我一直教导Class c(arg);Class c = arg;是两个完全等效的语句,但看这情形.

事实证明它们并不等同.第一个构造Class c出一个arg,而第二个构造一个Classout,arg然后复制构造Class c.请注意,允许实现省略该副本,并且通常会这样做.

Left l = Right(0);
Run Code Online (Sandbox Code Playgroud)

这需要转换RightIntermediary,以及转换IntermediaryLeft.标准不允许这两个顺序用户定义的转换,您必须至少执行以下其中一个转换:

Left l = (Intermediary)Right(0);
Run Code Online (Sandbox Code Playgroud)