【问题标题】:Unique Pointer as default parameter唯一指针作为默认参数
【发布时间】:2018-07-09 16:08:31
【问题描述】:

我试图将包装为唯一指针的空指针作为函数的默认参数。仅使用指针,标题可能看起来像这样

double f(A* vec = nullptr);

因为我确实需要使用 unique_ptr,所以我尝试将其更改为

double f(std::unique_ptr<A>& A vec = nullptr);

double f(std::unique_ptr<A>& A vec = std::unique_ptr<A>(nullptr));

这会导致错误

无法将“nullptr”从“std::nullptr_t”转换为“std::unique_ptr&”

无法将“std::unique_ptr&”类型的非常量左值引用绑定到“std::unique_ptr”类型的右值

分别。有没有办法做到这一点?我对 C++ 比较陌生,所以答案可能很明显。


与问题无关,但对我选择 unique_ptr 的解释:参数 vec 用作 f 中迭代的起始值,并与指针一起返回改进的值。计划是,如果没有给出起始值,则将指针设置为 nullptr,并在程序期间计算起始值。但是,由于我生成了一个新对象,所以从我看来,在裸指针上使用 unique_ptr 会更安全。

【问题讨论】:

  • 你是通过vec返回值吗?
  • 如何为引用变量设置默认值?它会参考什么?
  • 我认为在这里使用重载可能会更好,因为在无参数情况下会有额外的逻辑。
  • 您可以存储对唯一指针的 const 引用,这仍然允许您访问原始指针。
  • 这就是为什么我更喜欢使用哑指针作为函数参数的原因。在进行函数调用时,您始终可以在 unique_ptr 上使用 get 来获取其内部指针。

标签: c++ c++11 pointers unique-ptr


【解决方案1】:

我会说你在这里有两个选择。

1) 该函数不拥有它只是使用它的指针。在这种情况下,传递一个原始指针或(更好)一个引用(如果 nullptr 不是一个选项)。

// correct way to express a call to a non-owning function.
double f(A* vec = nullptr);

调用代码会使用这样的函数:

std::unique_ptr<A> vec;

f(vec.get()); // pass the raw pointer to the function

2) 该函数需要管理指针的生命周期或重新安装指针(拥有它),在这种情况下通过接受std::unique_ptr。 p>

// way to express transfer of ownership to a function
double f(std::unique_ptr<A> vec = std::unique_ptr<A>());

如果函数需要获取指针的所有权,确实不需要接受引用。

在讨论中出现了第三个选项。

3)如果你传入一个函数,函数应该修改指针,否则它将使用自己的内部指针。 p>

这很不寻常,但您可以使用一对像这样的重载函数来做到这一点:

// way to express a function that modifies a smart pointer
// (for example reseating it)
double f(std::unique_ptr<A>& vec);

// version where the uses doesn't want to supply the pointer
// and doesn't care about the modified value.
double f() 
{
    std::unique_ptr<A> vec; // a dummy
    f(vec); // pass in the dummy
}

【讨论】:

  • 这会转移所有权,但不清楚 OP 是否真的想要这个
  • @Slava 我猜,否则谁会拥有默认值?
  • OP 尝试使用原始指针转换函数,并且可能无法理解通过值传递 std::unique_ptr 的含义,从原始指针不清楚函数是否获得所有权
  • @Slava 但是他没有通过引用传递原始指针,所以我认为他不想更改指针。
  • @Slava :对于新代码,原始指针参数是非拥有的。 (处理遗留代码或 C 接口时会出现复杂情况。)
【解决方案2】:

第二个错误是因为您将非常量引用绑定到右值(它有点说)。如果这是必须的,则不能使用默认值,也不能使用 const 引用:

double f(const std::unique_ptr<A>& A vec = std::unique_ptr<A>(nullptr));

【讨论】:

  • @MartinBonner 我看到了,正准备写“嘿,这仍然不能修复绑定错误”,但随后消失了:D
【解决方案3】:
double f(std::unique_ptr<A>& vec = nullptr);

不起作用,因为编译器必须从 nullptr 创建一个临时的 std::unique_ptr。你用过吗

double f(std::unique_ptr<A> const& vec = nullptr);

编译器会接受它。

一种解决方法是超载。

double f(std::unique_ptr<A>& vec)
{
   return 0;
}

double f()
{
   std::unique_ptr<A> vec = nullptr;
   return f(vec);
}

【讨论】:

    猜你喜欢
    • 2011-05-25
    • 1970-01-01
    • 2012-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多