-1

Form academic point of view, if I wanted to return std::nullopt as a non-constant reference. How will I be doing the same.

Little background, today when I was working on a code returning an std::optional> reference but I forgot to make the return constant and I got the error.

Error (active)    E0434   a reference of type "std::optional<std::vector<std::any, std::allocator<std::any>>> &" (not const-qualified) cannot be initialized with a value of type "const std::nullopt_t"
Socket.IO   D:\Hardware\Windows\Visual Studio\Socket.IO\Socket.IO\main.cpp  46  

Error C2440   'return': cannot convert from 'const std::nullopt_t' to 'std::optional<std::vector<std::any,std::allocator<_Ty>>> &'
Socket.IO   d:\hardware\windows\visual studio\socket.io\socket.io\main.cpp  46

Just wanted to know if someone wanted to return an non-constant reference using std::optional how would he be doing so.

Platform Used : Windows 10 Pro x64

Development Environment : Visual Studios 15.9.9

std::vector<int>> a;
std::optional<std::vector<int>>& test(int b)
{
    a.clear();
    a.push_back(b);
    if(b)
         return a;
    else
         return std::nullopt;
}
Max Langhof
  • 23,383
  • 5
  • 39
  • 72
Dark Sorrow
  • 1,681
  • 14
  • 37
  • Returning a reference to a temporary value is a bad idea anyway, i.e. it would be undefined behaviour to access it. – PaulR Mar 19 '19 at 12:00
  • @PaulR, I am aware of that. I was returning a global variable which was only visible inside a file. – Dark Sorrow Mar 19 '19 at 12:07
  • 3
    No you aren't. both paths are returning a temporary – Caleth Mar 19 '19 at 12:07
  • 1
    Since you return a reference to `std::optional>`, not `std::vector` (which is the type of `a`) the `return a;` tries to return a reference to a temporary (constructed from `a`). – HolyBlackCat Mar 19 '19 at 12:09
  • You can create a `static std::optional> dummy;` within your function and then `return dummy;`. However, since you return by reference, anyone could change the value of `dummy` to an arbitrary value. I do not recommend doing so, but that's how you could do it. Returning a const-reference would be a little bit more safe. – pschill Mar 19 '19 at 12:10
  • It would be equally wrong to return a const reference. – molbdnilo Mar 19 '19 at 12:12
  • @molbdnilo Why would it be wrong to return a function local static variable by const reference? – pschill Mar 19 '19 at 12:13
  • @pschill There is no such thing in this code. – molbdnilo Mar 19 '19 at 12:14
  • 1
    @DarkSorrow May I boldly suggest you practice standard C++ [value based semantics](https://isocpp.org/wiki/faq/value-vs-ref-semantics)? I would not say "always" but "as much as you can". Ah, yes, using `auto` would also help a lot. – Chef Gladiator Mar 19 '19 at 12:16
  • @molbdnilo There is. It is the first sentence of my comment. – pschill Mar 19 '19 at 12:17
  • @pschill I was not responding to your comment, and returning a const reference to the other temporary would still be wrong. – molbdnilo Mar 19 '19 at 12:24

1 Answers1

6

std::nullopt is not a std::optional<std::vector<int>> (nor is a), it is an object that has an implicit conversion to that type.

You can't bind a non-const reference to a temporary, such as the result of a conversion.

I'm not sure you should be returning a reference to an optional, but rather an "optional reference". std::optional<std::vector<int> &> is not a valid type, but both std::vector<int> * and std::optional<std::reference_wrapper<std::vector<int>>> are, and they model "optional reference".

Caleth
  • 52,200
  • 2
  • 44
  • 75