Учитывая следующий код
#include <iostream>
using namespace std;
template <typename Type>
struct Something {
Something() {
cout << "Something()" << endl;
}
template <typename SomethingType>
Something(SomethingType&&) {
cout << "Something(SomethingType&&)" << endl;
}
};
int main() {
Something<int> something_else{Something<int>{}};
auto something = Something<int>{};
Something<int>{something};
return 0;
}
Я получаю следующий вывод
Something()
Something()
Something(SomethingType&&)
Почему конструктор копирования разрешается в шаблонный ссылочный конструктор пересылки, а не в конструктор перемещения? Я предполагаю, что это потому, что конструктор перемещения был неявно определен, но не конструктор копирования. Но я все еще запутался после прочтения случаев, когда конструктор копирования неявно не определен в переполнении стека.
Я предполагаю, что это потому, что конструктор перемещения был неявно определен, но не конструктор копирования.
Нет, оба неявно определены для класса Something
,
Почему конструктор копирования разрешается в шаблонный ссылочный конструктор пересылки
Поскольку конструктор копирования принимает const Something&
как его параметр. Это означает, что для вызова конструктора копирования требуется неявное преобразование const
Классификатор. Но может быть создан экземпляр перенаправляющего ссылочного конструктора Something&
в качестве его параметра, тогда это точное совпадение и выигрывает в разрешении перегрузки.
Так что если вы сделаете something
const
, неявно определенный конструктор копирования будет вызываться для 3-го случая вместо перенаправляющего ссылочного конструктора.
но не конструктор перемещения?
Потому что для конструктора перемещения вышеуказанная проблема не имеет значения. Для вызова 1-го и 2-го случая оба неявно определенных конструктора перемещения и ссылочный конструктор пересылки имеют точное совпадение, тогда не шаблонный конструктор перемещения выигрывает.
Других решений пока нет …