C++11 / 生成的构造函数

4

我一直在处理一个由其他人(已经离开公司)开始的C++项目。他编写了一段代码,似乎运行得很好,但我无法理解它。

下面是代码的简化版本:

有两个类:

class Algo_t {
protected :
    Matrix_t m_Matrix ;
public:
    Algo_t(Matrix_t && Matrix) {
        DoSomething();
    }
};

class Matrix_t {
protected :
    std::ifstream & m_iftsream ;
public:
    Matrix_t(std::ifstream && ifstream) {
        DoSomething();
    }
};

主函数中:

主函数中有以下调用:

char * pMyFileName = agrv[1] ;
Algo_t MyAlgo(ifstream(pMyFileName));

起初,我非常惊讶这段代码竟然没有任何错误,因为 Algo_t 没有接受 ifstream 作为参数的构造函数。更加令人惊奇的是,这段代码运行得非常好。

这个构造函数是由编译器生成的吗?还是 C++11 引入了一些新特性(如右值引用)?


1
也许类Matrix_t有一个ifstream转换运算符,或者一个接受ifstream的构造函数?哦,该死,它确实有...这就解释了一切... - barak manos
你的简化版本即使修复了一些明显的错误,仍然无法编译。 - Richard Critten
1
这几乎与使用带有const char []std::string构造结构相同,例如std::stringstream("Hello World!") - 您不需要显式执行std::stringstream(std::string("Hello World!")) - Holt
3个回答

8

在C++中,您最多可以使用一个用户定义的转换。您不能直接从ifstream构造Algo_t,但是您可以使用ifstream构造Matrix_t。因此,在

Algo_t MyAlgo(ifstream(pMyFileName));

编译器会构建一个临时的Matrix_t(您定义的一种用户转换),然后您使用该临时对象来构造MyAlgo

最多只能使用一个?如果我们尝试使用更多会发生什么? - CinCout
@CinCout 这样是行不通的。假设你有另一个类 Foo,可以从 Algo_t 构造。Foo MyFoo(ifstream(pMyFileName)); 是无法工作的。 - NathanOliver
1
你的回答 @NathanOliver 表达得有些奇怪,但是是正确的。 - Jean-Bernard Jansen

4

此处所述:

单参数构造函数:允许从特定类型进行隐式转换以初始化对象。

因此,由于构造函数的存在,从 ifstreamMatrix_t 存在隐式转换选项:

Matrix_t(std::ifstream && ifstream)

当你打电话时:

Algo_t MyAlgo(ifstream(pMyFileName));

ifstream(pMyFileName)对象转换为Matrix_t对象,然后通过构造函数Algo_t(Matrix_t && Matrix)进行使用。


3

您的矩阵构造函数被隐式调用,因为它采用ifstream&&。如果将其显式化,它将无法工作:

explicit Matrix_t(std::ifstream && ifstream) {
    DoSomething();
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接