operator* работает для std::unique_ptr<std::array<int, 5>>, но не для std::unique_ptr<int[]>. Но почему?
Из cppreference:
Эти функции-члены предоставляются только для unique_ptr для отдельных объектов, т. е. основного шаблона.
Здесь:
#include <vector>
#include <memory>
#include <algorithm>
#include <functional>
#include <fmt/core.h>
int main()
{
std::vector<int> data { 1, 2, 3, 4, 5 };
// auto ptr { std::make_unique_for_overwrite<std::array<int, 5> >() };
auto ptr{ std::make_unique_for_overwrite<int[]>(5) };
if (ptr == nullptr) return 1;
auto& out{ *ptr }; // does not compile for <int[]>
std::ranges::transform(data, std::begin(out), std::negate{});
for (const auto v : out)
fmt::print("{} ", v);
fmt::print("\n");
}
Сообщение об ошибке:
<source>:16:17: error: no match for 'operator*' (operand type is 'std::unique_ptr<int [], std::default_delete<int []> >')
16 | auto& out { *ptr };
| ^~~~
Как можно сделать out связанным с int[5], на которое указывает ptr? В основном я хочу сделать вызов transform скомпилированным для случая использования std::unique_ptr< int[] > ptr;.
Одно рабочее решение, которое приходит мне на ум:
// ...
auto out{ ptr.get() };
std::ranges::transform(data, out, std::negate{});
for (const auto v : std::span{ out, 5 })
// ...
Но есть ли другой способ сделать это, не касаясь необработанных указателей?
@Элджей С std::transform?
Что вы ожидаете от operator* примененного на std::unique_ptr< int[] > возврата?





Есть ли другой способ сделать это, не касаясь необработанных указателей?
Ваше текущее решение, на мой взгляд, является оптимальным.
Альтернативой может быть создание диапазона ссылок из std::make_unique<int[]> вызовом std::unique_ptr::operator[] для каждого элемента.
#include <ranges>
#include <memory>
#include <algorithm>
std::vector<int> data{ 1, 2, 3, 4, 5 };
auto ptr{ std::make_unique<int[]>(5) };
auto range = std::views::iota(0u, std::size(data))
| std::views::transform([&ptr](auto idx) -> int& { return ptr[idx]; });
std::ranges::transform(data, std::begin(range), std::negate{});
for (const auto v : range)
std::cout << v;
Вы можете использовать []?