Search code examples
c++-cliclr

How to use optional with a managed type


I want to create a function where there might be an exception and return optional if that's the case.

Here is a little code sample.

 optional<Exception^> opt;
        if (opt)
            MessageBox::Show("Error");

I get the following errors:

Error C3265 cannot declare a managed '_Value' in an unmanaged 'std::_Optional_destruct_base<_Ty,false>::$UnnamedClass$0x61d94762$23$' CLR d:\visualstudio\vc\tools\msvc\14.16.27023\include\optional 87

Error C2848 'std::_Optional_destruct_base<_Ty,false>::_Value': a managed type cannot be a member of a union CLR d:\visualstudio\vc\tools\msvc\14.16.27023\include\optional 87

Error C3699 '&&': cannot use this indirection on type '_Ty' CLR d:\visualstudio\vc\tools\msvc\14.16.27023\include\optional 431 Error C3699 '&&': cannot use this indirection on type 'const _Ty' CLR d:\visualstudio\vc\tools\msvc\14.16.27023\include\optional 435

Error C3699 '&&': cannot use this indirection on type '_Ty' CLR d:\visualstudio\vc\tools\msvc\14.16.27023\include\optional 467

Error C3699 '&&': cannot use this indirection on type 'const _Ty' CLR d:\visualstudio\vc\tools\msvc\14.16.27023\include\optional 476

So how can I use optional? Is it possible at all in C++ CLI? What are the alternatives?


Solution

  • My understanding of std::optional is that it's a value type that might not contain a value because something failed. The .Net standard way of dealing with a failure of this type is to throw an exception or to let an exception propagate out. However, it sounds like you don't want to do this, so here's the alternatives.

    For a .Net reference type (declared in C# as class, in C++/CLI as ref class or ref struct, used in C++/CLI with the ^), the way to deal with this is simply to return nullptr. Reference types are very, very rarely stored by value, and returning null is much more standard.

    For a .Net value type (declared in C# as struct, in C++/CLI as value class or value struct, used in C++/CLI without the ^), I would use System::Nullable<T>. Nullable is a type similar to Optional, where a value type is allowed to be null.