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:
#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;
}
Live Demo
Idea 2: Use boost::optional to pass a reference but still allow it to be empty. Unfortunately this doesn't work with std::optional because std::optional doesn't allow reference arguments.
#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;
}
Live Demo
Conclusion:
I would prefer boost::optional because it better expresses the intention.
foo.get()asconst Foo*for the client.unique_ptr, too, so it's not a new problem.