Умные указатели не могут быть автоматически использованы в качестве необработанных указателей? - PullRequest
2 голосов
/ 30 мая 2019

Я пытаюсь преобразовать коды для использования умных указателей вместо сырых указателей.Но было интересно - неужели нельзя использовать умные указатели в качестве необработанных указателей?

В этом примере:

#include <iostream>
#include <string>
#include <memory>

void printer(int* x)
{
    std::cout << "x = " << x << std::endl;
}

int main()
{   
    auto x = std::make_unique<int>(5);
    printer(x);
    return 0;
}

Я получаю ошибку:

In function 'int main()': 14:14: error: cannot convert
'std::unique_ptr<int, std::default_delete<int> >' to 'int*' for argument '1'
to 'void printer(int*)' 

Как это должно быть закодировано?Спасибо!

Ответы [ 2 ]

2 голосов
/ 30 мая 2019

Не может быть неявного преобразования, потому что неявное преобразование не имеет контекста, чтобы делать правильные вещи.printer принимает указатель, не являющийся владельцем, но как насчет других функций, которые должны стать собственниками?Например,

void kill(int *p) { delete p; }

Молчаливое преобразование при вызове kill(p); было бы неправильным!Это приведет к двойному удалению.Указатель не может знать, что он должен прекратить владеть объектом, он должен быть передан через вызов release.Все остальное было бы неправильно.

Поскольку интеллектуальные указатели предназначены только для принудительного применения явной семантики владения, преобразование в необработанный указатель также должно быть явным и иметь имя, которое сообщает о влиянии владения.

0 голосов
/ 30 мая 2019

std::make_unique<>() возвращает std::unique_ptr, что делает переменную x типа std::unique_ptr<int>.Эти умные указатели - не просто необработанные указатели, и вы не можете использовать их так же, как необработанные указатели.Вместо этого вы должны использовать метод get() на x, чтобы получить int*, на который он указывает.

...