从 unique_ptr 初始化 unique_ptr const 引用
initialize unique_ptr const reference from a unique_ptr
我用一个对象初始化了一个 unique_ptr。因为我想将它的引用传递给函数并且不让函数更改对象内容,所以我必须将 unique_ptr<const MyObject>&
传递给它。但是 gcc 5.4 不允许我从 uinque_ptr<MyObject>
.
初始化 unique_ptr<const MyObject>&
示例代码:
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: invalid initialization of reference of type ‘std::unique_ptr<const Foo>&’ from expression of type ‘std::unique_ptr<Foo>’
那么有什么合理的做法吗?
有两个问题:
- 如何
constify
unique_ptr
的指称。
- 如何将非拥有指针传递给函数。
传递非拥有指针的合理方法是传递原始指针:
some_function( my_unique_ptr.get() );
或者如果它不能为 null,那么您可以取消引用指针并传递引用,
some_function( *my_unique_ptr )
这意味着凝固与主要问题几乎无关,但是,这也是如何做到的:
unique_ptr<Foo> p{ new Foo() };
unique_ptr<const Foo> q{ move( p ) }; // Moves ownership!
一个 已经发布。
我只是想针对指针可能为空的情况提供一些额外的想法。
想法 1: 将指针包装到一个 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;
}
想法2:使用boost::optional
to pass a reference but still allow it to be empty. Unfortunately this doesn't work with 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;
}
结论:
我更喜欢boost::optional
,因为它更能表达意图。
我用一个对象初始化了一个 unique_ptr。因为我想将它的引用传递给函数并且不让函数更改对象内容,所以我必须将 unique_ptr<const MyObject>&
传递给它。但是 gcc 5.4 不允许我从 uinque_ptr<MyObject>
.
unique_ptr<const MyObject>&
示例代码:
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: invalid initialization of reference of type ‘std::unique_ptr<const Foo>&’ from expression of type ‘std::unique_ptr<Foo>’
那么有什么合理的做法吗?
有两个问题:
- 如何
constify
unique_ptr
的指称。 - 如何将非拥有指针传递给函数。
传递非拥有指针的合理方法是传递原始指针:
some_function( my_unique_ptr.get() );
或者如果它不能为 null,那么您可以取消引用指针并传递引用,
some_function( *my_unique_ptr )
这意味着凝固与主要问题几乎无关,但是,这也是如何做到的:
unique_ptr<Foo> p{ new Foo() };
unique_ptr<const Foo> q{ move( p ) }; // Moves ownership!
一个
我只是想针对指针可能为空的情况提供一些额外的想法。
想法 1: 将指针包装到一个 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;
}
想法2:使用boost::optional
to pass a reference but still allow it to be empty. Unfortunately this doesn't work with 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;
}
结论:
我更喜欢boost::optional
,因为它更能表达意图。