2016-08-01 3 views
4

Я работаю над проектом C++, запущенным кем-то еще (кто покинул компанию). Он написал фрагмент кода, который, кажется, работает очень хорошо, но я не могу этого понять.C++ 11/Генерируемый конструктор

Вот ниже упрощенной версии кода:

Есть два класса:

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)); 

Сначала я был очень удивлен, что код, составленный без ошибок, был se нет конструктора Algo_t, принимающего ifstream в качестве параметра. Я был более удивлен, заметив, что этот код работает очень хорошо.

Являются ли конструктором, сгенерированным компилятором, или есть какая-то новая функция, введенная C++ 11 (с rvalue ...)?

+1

Может быть, класс 'Matrix_t' имеет' оператор ifstream'-литья, или конструктор, который принимает 'ifstream'? О, черт возьми, это так ... Это объясняет это ... –

+0

Ваша упрощенная версия не скомпилируется даже после исправления некоторых очевидных ошибок. –

+1

Это (почти) такое же поведение, как при построении структуры, принимающей 'std :: string' с помощью' const char [] ', например. 'std :: stringstream (« Hello World! »)' - Вам не нужно явно делать 'std :: stringstream (std :: string (« Hello World! »))'. – Holt

ответ

8

В C++ вам разрешено до одного пользовательского преобразования. Вы не можете напрямую построить Algo_t от ifstream, но вы можете построить Matrix_t с ifstream. Таким образом, в

Algo_t MyAlgo(ifstream(pMyFileName)); 

Компилятор построить временный Matrix_t (ваш один и определенные пользователем преобразования), а затем использовать что временная построить MyAlgo

+0

До одного? Что произойдет, если мы попытаемся использовать больше? – CinCout

+1

@CinCout Код плохо сформирован. – Holt

+0

@CinCout Это не сработает. Допустим, у вас был другой класс 'Foo', который можно построить из' Algo_t'. 'Foo MyFoo (ifstream (pMyFileName));' не будет работать. – NathanOliver

3

Ваш матричный конструктор неявно называется, так как он принимает ifstream&&. Если вы сделаете это явно, это не будет работать:

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

Как пояснил here:

Конструкторы с одним аргументом: позволяют неявное преобразование из определенного типа для инициализации объекта.

Следовательно, существует неявный вариант преобразования из ifstream в Matrix_t из-конструктору:

Matrix_t(std::ifstream && ifstream) 

Итак, когда вы назвали:

Algo_t MyAlgo(ifstream(pMyFileName)); 

ifstream(pMyFileName) объекта преобразовать в Matrix_t объекта и затем используется конструктором Algo_t(Matrix_t && Matrix)

Смежные вопросы