Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

return optional from generic function in c++

Tags:

c++

templates

What's another way to return generic optional in c++, without using the optional<T>{} from BOOST library

Example

 template<class T>
    T search(T arg) {
        // this function is just to show the idea of what I am trying to ac
       if (found) return arg;
       return ?<---
    }

I mean if I know the most common type that will call this function I could

return T(-1); for int

return T("not found"); for string

return nullprt; for pointer type

But that defeat the purpose of generic. There must be another way right ? Thanks for helping

like image 618
mello Avatar asked Jan 04 '23 14:01

mello


1 Answers

First of all, boost::optional or std::optional were made exactly for that case. Is there a reason why you don't want to use them? Because most solutions will either mimic std::optional or they are a poor replacement.

Pass an output parameter by reference.

template <class T>
bool search( T arg, T & out );

Returns whether it has written the result to out or not. This can be a poor replacement because it requires the caller to construct an object of type T. If the caller itself is generic, then T either must be default-constructible or passed to the caller itself.

If you would usually return a reference, return a pointer instead.

template <class T>
const T & search( T arg );

can be replaced with

template <class T>
const T * search( T arg );

Please note, that std::optional does not support references to the same extent as boost::optional, so when using std::optional, you may really fall back to this when dealing with references.

Write an optional yourself.

I wouldn't recommend this. You have to put a lot of thought into it if you want to do it right. If you can live with the constraints of boost::optional or std::optional (in particular regarding thread-safety) I can't see a reason why you should to this.

Have a type trait that provides dummy values.

Reading your question again, you thought about keeping dummy values in a map. I would not recommend this, because, obviously, it is less generic and I can't see any benefits. But regarding the map, you would have a type trait that provides dummy values:

template <class T>
struct DummyValue;

template <>
struct DummyValue<int>
{
    static constexpr const int value = -1;
    // Or:
    // static int makeDummyValue();
};
// And so on ...
like image 94
Markus Mayr Avatar answered Jan 12 '23 18:01

Markus Mayr