[英]initialize unique_ptr const reference from a unique_ptr
I initialized an unique_ptr with an Object. 我用一个对象初始化了一个unique_ptr。 As i want to pass a reference of it to a function and don't let the function to change the object contents, I have to pass unique_ptr<const MyObject>&
to it. 因为我想将其引用传递给函数,并且不要让该函数更改对象内容,所以我必须将unique_ptr<const MyObject>&
传递给它。 But gcc 5.4 doesn't let me to initialize unique_ptr<const MyObject>&
from uinque_ptr<MyObject>
. 但是gcc 5.4不允许我从uinque_ptr<MyObject>
初始化unique_ptr<const MyObject>&
。
Example Code: 示例代码:
class Foo{public int x;};
unique_ptr<Foo> foo(new Foo());
foo->x = 5;
// User shouldn't be able to touch bar contents.
unique_ptr<const Foo>& bar = foo;
C++ error: C ++错误:
error: invalid initialization of reference of type ‘std::unique_ptr<const Foo>&’ from expression of type ‘std::unique_ptr<Foo>’
So is there any reasonable way to do it? 那么有什么合理的方法吗?
There are two issues: 有两个问题:
constify
the referent of a unique_ptr
. 如何constify
unique_ptr
的引用对象。 The reasonable way to pass a non-owning pointer is to pass a raw pointer: 传递非所有者指针的合理方法是传递原始指针:
some_function( my_unique_ptr.get() );
Or if it can't be null then you can dereference the pointer and pass a reference, 或者,如果不能为null,则可以取消引用指针并传递引用,
some_function( *my_unique_ptr )
This means that the constification is pretty much irrelevant to the main issue, but still, here's how to do that also: 这意味着构象与主要问题几乎没有关系,但是仍然可以通过以下方法做到这一点:
unique_ptr<Foo> p{ new Foo() };
unique_ptr<const Foo> q{ move( p ) }; // Moves ownership!
A valid answer has already been posted. 有效答案已经发布。
I just want to provide some additional ideas for the case that the pointer could be empty. 我只想为指针可能为空的情况提供一些其他想法。
Idea 1: Wrap the pointer into a std::shared_ptr
with empty deleter: 想法1:使用空的Deleter将指针包装到std::shared_ptr
:
#include <iostream>
#include <memory>
struct Foo{ int x; };
void Fun( std::shared_ptr<const Foo> p ) {
if( p )
std::cout << "p.x: " << p->x << std::endl;
//won't compile:
//delete p;
}
int main(){
std::unique_ptr<Foo> foo(new Foo());
foo->x = 5;
std::shared_ptr<const Foo> bar( foo.get(), []( const Foo* ){} );
Fun( bar );
return 0;
}
Idea 2: Use boost::optional
to pass a reference but still allow it to be empty. 想法2:使用boost::optional
传递引用,但仍允许其为空。 Unfortunately this doesn't work with std::optional
because std::optional
doesn't allow reference arguments. 不幸的是,这不适用于std::optional
因为std::optional
不允许引用参数。
#include <iostream>
#include <memory>
#include <boost/optional.hpp>
struct Foo{ int x; };
using OptionalFooConstRef = boost::optional<Foo const&>;
void Fun( OptionalFooConstRef p ){
if( p )
std::cout << "p.x: " << p->x << std::endl;
else
std::cout << "no foo\n";
//won't compile:
//delete p;
}
int main(){
std::unique_ptr<Foo> foo(new Foo());
foo->x = 5;
Fun( foo ? OptionalFooConstRef( *foo ) : boost::none );
std::unique_ptr<Foo> nofoo;
Fun( nofoo ? OptionalFooConstRef( *nofoo ) : boost::none );
return 0;
}
Conclusion: 结论:
I would prefer boost::optional
because it better expresses the intention. 我更喜欢boost::optional
因为它可以更好地表达意图。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.