Почему пересылаемый ссылочный конструктор вызывается вместо конструктора копирования?

Учитывая следующий код

#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&&)

Почему конструктор копирования разрешается в шаблонный ссылочный конструктор пересылки, а не в конструктор перемещения? Я предполагаю, что это потому, что конструктор перемещения был неявно определен, но не конструктор копирования. Но я все еще запутался после прочтения случаев, когда конструктор копирования неявно не определен в переполнении стека.

3

Решение

Я предполагаю, что это потому, что конструктор перемещения был неявно определен, но не конструктор копирования.

Нет, оба неявно определены для класса Something,

Почему конструктор копирования разрешается в шаблонный ссылочный конструктор пересылки

Поскольку конструктор копирования принимает const Something& как его параметр. Это означает, что для вызова конструктора копирования требуется неявное преобразование const Классификатор. Но может быть создан экземпляр перенаправляющего ссылочного конструктора Something& в качестве его параметра, тогда это точное совпадение и выигрывает в разрешении перегрузки.

Так что если вы сделаете something const, неявно определенный конструктор копирования будет вызываться для 3-го случая вместо перенаправляющего ссылочного конструктора.

ЖИТЬ

но не конструктор перемещения?

Потому что для конструктора перемещения вышеуказанная проблема не имеет значения. Для вызова 1-го и 2-го случая оба неявно определенных конструктора перемещения и ссылочный конструктор пересылки имеют точное совпадение, тогда не шаблонный конструктор перемещения выигрывает.

4

Другие решения

Других решений пока нет …