如何取消引用std::unique_ptr<int[]>?

huangapple go评论77阅读模式
英文:

How to dereference std::unique_ptr<int[]>?

问题

The operator* works for std::unique_ptr<std::array<int, 5>> but not for std::unique_ptr<int[]>. But why?

来自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 绑定到 ptr 指向的 int[5]?我基本上想使调用 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 })
// ...

但是否有其他方法可以在不使用原始指针的情况下完成这个操作?

英文:

The operator* works for std::unique_ptr&lt;std::array&lt;int, 5&gt;&gt; but not for std::unique_ptr&lt;int[]&gt;. But why?

Coming from cppreference:
> These member functions are only provided for unique_ptr for the single objects i.e. the primary template.

Here:

#include &lt;vector&gt;
#include &lt;memory&gt;
#include &lt;algorithm&gt;
#include &lt;functional&gt;
#include &lt;fmt/core.h&gt;

int main()
{
    std::vector&lt;int&gt; data { 1, 2, 3, 4, 5 };

    // auto ptr { std::make_unique_for_overwrite&lt;std::array&lt;int, 5&gt; &gt;() };
    auto ptr{ std::make_unique_for_overwrite&lt;int[]&gt;(5) };
    if (ptr == nullptr) return 1;
    auto&amp; out{ *ptr }; // does not compile for &lt;int[]&gt;
    std::ranges::transform(data, std::begin(out), std::negate{});

    for (const auto v : out)
        fmt::print(&quot;{} &quot;, v);
    fmt::print(&quot;\n&quot;);
}

Error message:

&lt;source&gt;:16:17: error: no match for &#39;operator*&#39; (operand type is &#39;std::unique_ptr&lt;int [], std::default_delete&lt;int []&gt; &gt;&#39;)
   16 |     auto&amp; out { *ptr };
      |                 ^~~~

How can out be made bound to int[5] that is pointed to by ptr? I basically want to make the call to transform compile for the case of using a std::unique_ptr&lt; int[] &gt; ptr;.

One working solution that comes to my mind:

// ...
auto out{ ptr.get() };
std::ranges::transform(data, out, std::negate{});

for (const auto v : std::span{ out, 5 })
// ...

But is there another way of doing this without having to touch raw pointers?

答案1

得分: 3

是否有另一种方法可以在不必接触原始指针的情况下完成这个任务?

在我看来,你当前的解决方案是最优的。

另一种方法可能是通过在每个元素上调用std::unique_ptr::operator[]来创建一个引用范围,将std::make_unique&lt;int[]&gt;转换为引用范围。

#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;

在godbolt.org上查看在线演示

英文:

>Is there another way of doing this without having to touch raw pointers?

Your current solution is far optimal in my opinion.

An alternative might be making a reference-range out of the std::make_unique&lt;int[]&gt; by calling the std::unique_ptr::operator[] on each element.

#include &lt;ranges&gt;
#include &lt;memory&gt;
#include &lt;algorithm&gt;

std::vector&lt;int&gt; data{ 1, 2, 3, 4, 5 };
auto ptr{ std::make_unique&lt;int[]&gt;(5) };

auto range = std::views::iota(0u, std::size(data))
      | std::views::transform([&amp;ptr](auto idx) -&gt; int&amp; { return ptr[idx]; });

std::ranges::transform(data, std::begin(range), std::negate{});

for (const auto v : range)
    std::cout &lt;&lt; v;

See live demo in godbolt.org

huangapple
  • 本文由 发表于 2023年6月26日 06:12:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/76552613.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定