convert nullptr to std::optional - c++

I have a library defining method() that returns type V* and can return nullptr. What's the best way to wrap that method to turn the value into a std::optional<V>?
The naive way would be something like:
std::optional<V> maybe_value;
V* value = method();
if (value != nullptr) {
maybe_value = *value; // assuming the type is even copyable
}
But I was hoping there'd already be some STL function I could use to do this as a one-liner wrapper around method().

Your way looks basically fine to me, and is roughly what I'd do. You don't want a one-liner here as it would not be very clear. Ultimately you can create a function for it if you like.
One concern: be very careful with ownership semantics here. Who owns *value? Can it be copied? Is that meaningful? Can you move it instead? Who frees the original object?
Always ask these questions when passed a pointer, even if it appeared that the pointer was only chosen in order to add nullability.
To be quite honest, although std::optional is preferable in new code (or code you're refactoring), I'm not convinced that wrapping a function like this is worth the potential confusion, not to mention the cost of a copy (if, indeed, that is necessary).

There is no such function. Assignment of any value makes the optional containing a value. But you can provide your own
template <typename T>
std::optional<T*> optional_ptr(T* ptr) {
return ptr ? std::optional<T*>(ptr) : std::optional<T*>();
}

Related

Smart pointers with functions returning a pointer in an argument

This question was discussed a few times but all those discussions almost a decade old and there was no good solution. The question is the same.
We have smart pointers, like unique_ptr, that is great. We have tons of C functions returning a pointer to an object as an argument which later needs to be released.
Let's say this is the function:
int CreateSomething(OBJECT_TYPE** pObject);
So, what would we normally do without smart pointers? Apparently something like that:
OBJECT_TYPE* pObject;
if(CreateSomething(&pObject) == 0) {
// Use the pObject pointer
delete pObject;
}
Now, I would like to rewrite it using smart pointers, and I would like it to be as simple as this:
unique_ptr<OBJECT_TYPE> pObject;
if(CreateSomething(&pObject) == 0) {
// Use the pObject pointer
}
Technically, that would be quite possible if unique_ptr would have T** operator&, and if it would count on this kind of workflow, but it doesn't.
In the case when we want to use a smart pointer here, we have to declare a regular pointer, use it in that function, and then reassign it to the smart pointer. But those extra steps can and should be eliminated, and I hope that maybe there is already an implementation which would allow me to do what I need in that simple manner as I showed.
Yes, I can write my own smart pointer or mediator, which would simplify the usage of unique_ptr, but first I'd like to ask if maybe there is already something implemented in the depth of standard libraries for this and I simply overlooked it?
C++23 has very recently added std::out_ptr for exactly this use case.
write a wrapper: (uncompiled code)
namespace smart_ptrs {
std::unique_ptr<OBJECT_TYPE> CreateSomething() {
OBJECT_TYPE *p = nullptr;
if (::CreateSomething(&p))
return std::unique_ptr<OBJECT_TYPE>(p);
return std::unique_ptr<OBJECT_TYPE>();
}
Then you can write:
std::unique_ptr<OBJECT_TYPE> ptr = smart_ptrs::CreateSomething();
if (ptr) {
// Use the pObject pointer
}
In the case when we want to use a smart pointer here, we have to declare a regular pointer, use it in that function, and then reassign it to the smart pointer.
Basically, yes. That is exactly what you must do (for now anyway, until std::out_ptr is added in C++23).
C++ smart pointers simply do not expose access to their held pointer, thus no way for you to obtain its address to pass to the C function. So, you have to use the smart pointer's constructor or assignment operator instead, which requires the object pointer to already be initialized first.
I'd like to ask if maybe there is already something implemented in the depth of standard libraries for this and I simply overlooked it?
You have not overlooked anything.

C++ Move Constructor With Pointers (*&& Syntax)

I would like to know if there are any problems with the construction <type>*&& in C++. Let me give a concrete example.
Say we have a class that should be constructed from an array. We would usually do something like this:
class Things
{
public:
Things(const ThingType* arrayOfThings, int sizeOfArray)
: myArray(new ThingType[sizeOfArray])
{
for (int i = 0; i < sizeOfArray; i++)
myArray[i] = arrayOfThings[i];
}
private:
ThingType* myArray;
}
This is fine if we want to preserve arrayOfThings, because we are doing a deep copy of it. Moreover, by using const we are ensuring it won't be modified inside the constructor.
But suppose our program has a lot of statements like this one:
Things myThings(new ThingType[9001] {thing_0, ... , thing_9000}, 9001);
This might seem weird, but it may happen that the huge ThingType array is returned from a function as a rvalue.
In that case, we don't care about preserving the pointer passed as a parameter. In fact, we definitely don't want to do a deep copy of it, because it would be a huge waste of time preserving something we are about to destroy anyways.
One possible solution to this would to add another constructor that would handle the case of a non-const rvalue ThingType pointer, like a general move constructor handles the case of a non-const rvalue instance of the class:
public:
Things(ThingType*&& arrayOfThings, int sizeOfArray)
: myArray(arrayOfThings)
{
arrayOfThings = NULL;
}
This seems to be solving the problem for me, but I did not find much information about the <type>*&& construction seen above. Is it kosher, or will I be sent to the dungeons for mixing pointers and references?
After some time I believe I found satisfactory - although far from optimal - solutions. Since no one answered the question, I will share the best workarounds I found.
As Justin pointed out, using ThingType*&& can lead to trouble when we take the address of a variable of ThingType (but not of a ThingType pointer, as he implied in his answer) in the constructor call.
If t is a ThingType, the expression &t is an r-value of type ThingType*, so Thing myThing(&t, ...) will call the move constructor, with the result of making myThing.myArray point to t. This is not what we would want in most cases.
One solution is to use vectors instead of arrays, as illustrated below:
// Copy
explicit Things(const std::vector<ThingType>& vectorOfThings)
: myVector(vectorOfThings)
{ }
// Move
explicit Things(std::vector<ThingType>&& vectorOfThings)
: myVector(std::move(vectorOfThings))
{ }
The move constructor would then be used in situations like this:
Things myThings(vector<ThingType>{thing_0, ... , thing_9000});
Although this solves the problem, it is not feasible if we are dependent on an API which returns raw pointers, or if we want don't want to give up arrays. In this case, we can use smart pointers to solve the problem.
Suppose, we have a function ThingType* generateArray() which we want to use to initialize our object of type Things. The first thing we should do is to wrap this function with another function that returns a smart pointer instead.
unique_ptr<ThingType[]> generateSmartPointer()
{
return unique_ptr<ThingType[]>(generateArray());
}
Here I used a unique_pointer, but this could change depending on the implementation.
Now we add a new constructor to Things, with a instance of unique_ptr as an argument. This will act as the move constructor for arrays of ThingType:
Things(unique_ptr<ThingType[]> thingsPointer, int sizeOfArray)
: myArray(thingsInput.release()), size(sizeOfArray)
{ }
unique_ptr<T>.release() is used to get the array, and at the same time make the unique pointer release ownership of it, preventing the array from being deleted once the unique pointer is destroyed.
And that's it. These are the two best solutions I found to this problem, and while they are far from perfect, they have worked so far considering the objectives for each implementation.

Missing shared_ref

While working with std::shared_ptr a lot I kind of miss a shared_ref implementation. That is a specialization of shared_ptr, which guarantees, that it never wraps a nullptr (given right usage, of course).
I kind of wonder why it is not in the C++11 standard. Are there any mayor problems when implementing it? On the top of my head I cannot think of any.
EDIT:
I would expect to have an interface similar to:
template <typename T>
class shared_ref {
public:
shared_ref( T&& ref );
T& get();
T* operator&() const;
template< class Y >
void reset( Y&& obj );
long use_count() const;
bool unique() const;
void swap( shared_ref& r );
};
Are there any mayor problems when implementing it?
Here's one: you can't take ownership of a reference. The whole point of a smart pointer is to claim ownership of the pointer itself. shared_ref can't work because you can't control the lifetime of a reference.
And no, this isn't going to fly either:
shared_ref( T&& ref ) : p(&ref) {}
The user may have given you a stack variable, which now means you have "shared" ownership between this object and a stack variable. And stack variables cannot share ownership with something.
You can only control the lifetime of a pointer. And pointers can be NULL. Therefore, the only thing you can do is a runtime check to see if a pointer is NULL.
The absolute best you can do is an interface equivalent to shared_ptr except that it has no default constructor and throws in the event of being given NULL. Is that really worth creating a whole new pointer type over?
The C++ Core Guidelines support library has the not_null template, which can be applied to most pointer-like types. So you can use not_null<shared_ptr> when you want to verify that a pointer isn't NULL, but only once when it enters use. After the initial creating of the pointer, it doesn't need to check again.
Granted, you can't force other people to use them, but use of the type consistently will resolve the issue.
There are only two ways for a shared_ptr to be null - either it was default constructed, or it was assigned a null value at some point. Since you already agree it doesn't make sense to default construct your hypothetical shared_ref class, that leaves only the second condition.
If you tried to assign a nullptr to your shared_ref object, what would you expect to happen? Should it throw an error? It's trivial to do the same thing with a regular shared_ptr using a simple template function:
template<typename T>
T* notnull(T* ptr)
{
if (ptr == std::nullptr)
throw std::invalid_argument(std::string("nullptr"));
return ptr;
}
std::shared_ptr<int> pint = notnull(GetIntPtr());
Generally things aren't added to the standard unless there's a compelling need with no easy workarounds.

C++ pointer container with reference counting

I need a collection in which i can store heap-allocated objects having virtual functions.
I known about boost::shared_ptr, std::unique_ptr (C++11) and boost::ptr_(vector|list|map), but they doesn't solve duplicate pointer problem.
Just to describe a problem - i have a function which accepts heap-allocated pointer and stores it for future use:
void SomeClass::add(T* ptr)
{
_list.push_back(ptr);
}
But if i call add twice with same parameter ptr - _list will contain two pointers to same object and when _list is destructed multiple deletion of same object will occur.
If _list will count pointer which he stores and uses them at deletion time then this problem will be solved and objects will not be deleted multiple times.
So the question is:
Does somebody knows some library with collections (vector,list,map in essence) of pointer with auto-delete on destruction and support of reference counting?
Or maybe i can solve this problem using some other technique?
Update:
I need support of duplicate pointers. So i can't use std::set.
As Kerrek SB and Grizzly mentioned - it is a bad idea to use raw pointers in general and suggests to use std::make_shared and forget about instantiation via new. But this is responsibility of client-side code - not the class which i designs. Even if i change add signature (and _list container of course) to
void SomeClass::add(std::shared_ptr<T> ptr)
{
_list.push_back(ptr);
}
then somebody (who doesn't know about std::make_shared) still can write this:
SomeClass instance;
T* ptr = new T();
instance.add(ptr);
instance.add(ptr);
So this is not a full solution which i wait, but useful if you write code alone.
Update 2:
As an alternative solution i found a clonning (using generated copy constructor). I mean that i can change my add function like this:
template <typename R>
void SomeClass::add(const R& ref)
{
_list.push_back(new R(ref));
}
this will allow virtual method (R - class which extends some base class (interface)) calls and disallow duplicate pointers. But this solution has an overhead for clone.
Yes: std::list<std::shared_ptr<T>>.
The shared pointer is avaiable from <memory>, or on older platforms from <tr1/memory>, or from Boost's <boost/shared_ptr.hpp>. You won't need to delete anything manually, as the shared pointer takes care of this itself. You will however need to keep all your heap pointers inside a shared pointer right from the start:
std::shared_ptr<T> p(new T); // legacy
auto p = std::make_shared<T>(); // better
If you another shared pointer to the same object, make a copy of the shared pointer (rather than construct a new shared pointer from the underlying raw pointer): auto q = p;
The moral here is: If you're using naked pointers, something is wrong.
Realize that smart pointers are compared by comparing the underlying container. So you can just use a std::set of whatever smartpointer you prefer. Personally I use std::unique_ptr over shared_ptr, whenever I can get away with it, since it makes the ownership much clearer (whoever holds the unique_ptris the owner) and has much lower overhead too. I have found that this is enough for almost all my code. The code would look something like the following:
std::set<std::unique_ptr<T> > _list;
void SomeClass::add(T* ptr)
{
std::unique_ptr<T> p(ptr);
auto iter = _list.find(p);
if(iter == _list.end())
_list.insert(std::move(p));
else
p.release();
}
I'm not sure right now if that is overkill (have to check if insert is guaranteed not to do anything, if the insertion fails), but it should work. Doing this with shared_ptr<T> would look similar, although be a bit more complex, due to the lack of a relase member. In that case I would probably first construct a shared_ptr<T> with a do nothing deleter too pass to the call to find and then another shared_ptr<T> which is actually inserted.
Of course personally I would avoid doing this and always pass around smart pointers when the ownership of a pointer changes hands. Therefore I would rewrite SomeClass::add as void SomeClass::add(std::unique_ptr<T> ptr) or void SomeClass::add(std::shared_ptr<T> ptr) which would pretty much solve the problem of having multiple instances anyways (as long as the pointer is always wrapped).

Getter and setter, pointers or references, and good syntax to use in c++?

I would like to know a good syntax for C++ getters and setters.
private:
YourClass *pMember;
the setter is easy I guess:
void Member(YourClass *value){
this->pMember = value; // forget about deleting etc
}
and the getter?
should I use references or const pointers?
example:
YourClass &Member(){
return *this->pMember;
}
or
YourClass *Member() const{
return this->member;
}
whats the difference between them?
Thanks,
Joe
EDIT:
sorry, I will edit my question... I know about references and pointers, I was asking about references and const pointers, as getters, what would be the difference between them in my code, like in hte future, what shoud I expect to lose if I go a way or another...
so I guess I will use const pointers instead of references
const pointers can't be delete or setted, right?
As a general law:
If NULL is a valid parameter or return value, use pointers.
If NULL is NOT a valid parameter or return value, use references.
So if the setter should possibly be called with NULL, use a pointer as a parameter. Otherwise use a reference.
If it's valid to call the getter of a object containing a NULL pointer, it should return a pointer. If such a case is an illegal invariant, the return value should be a reference. The getter then should throw a exception, if the member variable is NULL.
Your code looks a great deal as if you're accustomed to a different language -- in C++ using this->x (for one example) is relatively unusual. When the code is at all well written, so is using an accessor or mutator.
Though I'm fairly unusual in this particular respect, I'll go on record (yet again) as saying that forcing client code to use an accessor or mutator directly is a bad idea. If you honestly have a situation where it makes sense for client code to manipulate a value in your object, then the client code should use normal assignment to read and/or write that value.
When/if you need to control what value is assigned, operator overloading lets you take that control without forcing ugly get/set syntax on the client code. Specifically, what you want is a proxy class (or class template). Just for one example, one of the most common situations where people want get/set functions is something like a number that's supposed to be restricted to some particular range. The setXXX checks the new value for being in range, and the getXXX returns the value.
If you want that, a (fairly) simple template can do the job much more cleanly:
template <class T, class less=std::less<T> >
class bounded {
const T lower_, upper_;
T val_;
bool check(T const &value) {
return less()(value, lower_) || less()(upper_, value);
}
void assign(T const &value) {
if (check(value))
throw std::domain_error("Out of Range");
val_ = value;
}
public:
bounded(T const &lower, T const &upper)
: lower_(lower), upper_(upper) {}
bounded(bounded const &init)
: lower_(init.lower), upper_(init.upper)
{
assign(init);
}
bounded &operator=(T const &v) { assign(v); return *this; }
operator T() const { return val_; }
friend std::istream &operator>>(std::istream &is, bounded &b) {
T temp;
is >> temp;
if (b.check(temp))
is.setstate(std::ios::failbit);
else
b.val_ = temp;
return is;
}
};
This also makes the code much closer to self documenting -- for example, when you declare an object like: bounded<int>(1, 1024);, it's immediately apparent that the intent is an integer in the range of 1 to 1024. The only part somebody might find open to question is whether 1 and/or 1024 is included in the range. This is considerably different from defining an int in the class, and expecting everybody who ever looks at the class to realize that they're supposed to use the setXXX to enforce some (at that point unknown) set of bounds on the values that can be assigned.
When you embed one of these in a class, you make it a public variable, and the range is still enforced. In the client code, there's no real argument over syntax -- you're just assigning to a public variable, like you would any other -- with the minor detail that attempting to assign a value that's out of range will throw an exception. In theory, the class should probably take a policy template-parameter to specify exactly what it does in that case, but I've never had a real reason to bother with that.
The best thing is to provide a real OO interface to the client that hides implementaton details. Getters and Setters are not OO.
As others have said, use pointers if null is a possibility.
In most cases, I prefer to use references when possible. Personally, in my code, I like to use the distinction between pointers and references to signal ownership. I think of calls with references as "loaning" an object to another function or class. The original class that passed or returned the reference still owns it, and is responsible for its creation, maintenance and clean up. When my code passes a non-const pointer, on the other hand, it usually means that there's some kind of transfer or sharing of ownership going on, with all the responsibilities that entails.
(And yes, I usually use smart pointers. Those are akin to references in my mind. I'm talking about lower level code than that here.)
whats the difference between them?
The reference is an alias of the thing(it is the thing*). A pointer is the address of the thing. If there's a chance that what's pointed to won't be there, then you probably don't want to return references. References tell the caller "I'm going to give you an alias that will exist when I return it to you". In fact there's really no way to check the reference to see if what's underlying is valid.
With the pointer, semantically, you are implying that the caller may wish to check to see if Member exists before using it. Ussually this is done with a NULL check.
Ultimately there's no "right" answer. It depends on the class's contract and if the caller will/should/wants to check whether "Member" is still around.
The short answer is pointers for things that can be pointed elsewhere and references for "unseated" aliases.
In addition to the other answers, if you choose references for the getter don't write it like in your example:
YourClass &Member(){
return *this->pMember;
}
Your getter actually allows setting, as in instance->Member() = YourClass(); and thus bypassing your setter. This might not be allowed if YourClass is noncopyable, but is still another thing to have in mind. Another drawback is the getter is not const.
Instead, write your getter like this:
const YourClass &Member() const {
return *this->pMember;
}
+1 on questioning the use of setters and getters. If you must use them and have the possibility of nulls consider using boost::shared_ptr. This way ownership is handled for you.
Jonathan, what compiler are you using? There's a great chance that shared_ptr already comes shipped with it as part of the compiler's TR1 implementation.