Ошибка clang с std:: unique_ptr

У меня есть базовый объект с именем IList. Тогда у меня есть VectorList, который наследует IList.

то у меня есть такая функция:

std::unique_ptr<IList> factory(){
    auto vlist = std::make_unique<VectorList>();
    return vlist;
}

Это компилируется без проблем в gcc, но clang дает следующую ошибку:

test_file.cc:26:9: error: no viable conversion from 'unique_ptr<VectorList, default_delete<VectorList>>' to
      'unique_ptr<IList, default_delete<IList>>'
        return vlist;

Как правильно обращаться с такими ошибками?

Ответ 1

Появляется (ваша версия). Clang по-прежнему придерживается поведения С++ 11 в этом отношении. В С++ 11 вам пришлось использовать std::move в этом случае, потому что тип vlist отличается от типа возвращаемого значения, и поэтому предложение "при возврате lvalue, сначала попробуйте его как rvalue" не применяются.

В С++ 14 это ограничение "одинаковых типов" было отменено, поэтому в С++ 14 вам не нужно использовать std::move в операторе return. Но если вам нужен код для компиляции с вашей текущей инструментальной цепочкой, просто добавьте его туда:

return std::move(vlist);

Точная формулировка С++ 11 такова:

12.8/32 Когда критерии для исключения операции копирования выполняются или выполняются, за исключением того, что источник object - это параметр функции, а подлежащий копированию объект определяется значением lvalue, разрешением перегрузки до выберите конструктор для копии сначала, как если бы объект был обозначен rvalue....

Необходимо выполнить критерии для копирования (включая "тот же тип" ); они просто немного расширены для покрытия параметров.

В С++ 14 (N4140) формулировка шире:

12.8/32 Когда критерии для исключения операции копирования/перемещения выполняются, но не для объявления исключения, и объект, подлежащий копированию, обозначается lvalue, или когда выражение в выражении return является (возможно, в скобках) id-выражение, которое называет объект с автоматическим временем хранения, объявленным в теле или Параметр-объявление-предложение самой внутренней функции включения или лямбда-выражения,. для выбора конструктора для копии сначала выполняется так, как если бы объект был обозначен rvalue.

(Акцент мой)

Как вы можете видеть, для случая return больше не требуются копии критериев элиции.