I want a function to return an optional reference to an object. Idea is to avoid copy, but seems like i should not be using according to this discussion: std::optional specialization for reference types
Lets say I have a map of objects, and I want my function to return a reference to an object, if it is exists in the map. What is the best way?
struct HeavyObj;
std::map<int, HeavyObj> my_map;
std::optional<HeavyObj&> get_obj(int key){
if(auto it = my_map.find(key); it != my_map.end()){
return std::optional<HeavyObj&>{ ? };
} else {
return {};
}
ps: needed for C++17
update, If I use a pointer, I get:
#include <optional>
#include <map>
struct HeavyObj{
int data;
};
static std::map<int, HeavyObj> my_map;
std::optional<HeavyObj*> get_obj(int key){
if(auto it = my_map.find(key); it != my_map.end()){
return std::optional<HeavyObj*>{&(*it)};
} else {
return {};
}
}
int main(){
auto test = get_obj(3);
return 0;
}
// gcc -std=c++17 -Wall optional.cc -lstdc++
optional.cc: In function ‘std::optional<HeavyObj*> get_obj(int)’:
optional.cc:13:47: error: no matching function for call to ‘std::optional<HeavyObj*>::optional(<brace-enclosed initializer list>)’
13 | return std::optional<HeavyObj*>{&(*it)};
| ^
```
As mentioned, you can use the fact that an uninitialized pointer is nullptr
to mimic the optional
behavior.
However, some people might consider it cleaner to use optional
anyway as it is more consistent if you have a similar function returning an optional
int
for instance.
You can use the std::nullopt
when the value is not found and simply return the value if it is found (the compiler will do the cast from HeavyObject* to optional<HeavyObject*> but you can do it manually).