Variant optional to return error string or value I needed a class with more information than optionals give, I need to know why the optional is not valid in error states. I used a Boost variant for this. Since this will be wrapping almost all of my return values, I need to know if it's as fast as possible (i.e. did I do move semantics and all that jazz properly?).

template&lt;typename T&gt;
class Result
{
public:
    Result(const std::string&amp; errorString) {
        contents = errorString;
    }

    Result(T&amp;&amp; value) {
        contents = std::forward&lt;T&gt;(value);
    }

    operator bool() {
        //is the active value our T
        return contents.which() == 0;
    }

    T unwrap() {
        return boost::get&lt;T&gt;(contents);
    }

    std::string unwrapErr() {
        return boost::get&lt;std::string&gt;(contents);
    }

private:
    boost::variant&lt;T, std::string&gt; contents;
};


Example use

Result&lt;std::vector&lt;int&gt;&gt; foo()
{
    if(success)
         return Result&lt;std::vector&lt;int&gt;&gt;({1,2,3});
    else
         return Result&lt;std::vector&lt;int&gt;&gt;("failure reason");
}

if(auto vec = foo())
   vec.unwrap() //do stuff to contained value
else
   std::cout &lt;&lt; vec.unwrapErr();
You said:


  I need to know if it's as fast as possible


The only thing I could think of that would make your program potentially faster is:

Initialize the member variable using initialization list syntax

Result(const std::string&amp; errorString) : contents(errorString) {}

// boost::variant already has a constructor that takes a rvalue reference.
Result(T&amp;&amp; value) : conents(value) {}


Other suggestions:

Add operator T functions instead of unwrap

This may be a matter of stylistic preference but I think it is better to use:

Result&lt;int&gt; r = &lt;some function call&gt;;
if ( r &amp;&amp; r == 10 )
{
    // Do something with r
}


than

Result&lt;int&gt; r = &lt;some function call&gt;;
if ( r &amp;&amp; r.unwrap() == 10 )
{
    // Do something with r
}


You can use the former syntactic construct by providing const and non-const versions of user defined conversion operators.

operator T const&amp; () const
{
   return boost::get&lt;T&gt;(contents);
}
operator T&amp; ()
{
   return boost::get&lt;T&gt;(contents);
}


Decide how to deal with use of Result&lt;std::string&gt;

If you use Result&lt;std::string&gt;, the function operator bool will always return true. For that use case, there is no way to tell whether a function returned with success or failure.

One way to deal with the problem will be to prevent use of Result&lt;std::string&gt; using static_assert.

static_assert(std::is_same_type&lt;T, std::string&gt;::value == false,
              "Can't use std::string as template paramete");


Use a better name than unwrapErr()

I would prefer to use something like getError() or getErrorString().

Update

The operator T functions will be problem when T is bool. If you like to use the operator T functions for all types, it will be better to change operator bool to a different function, such as isGood().

bool isGood() {
    //is the active value our T
    return contents.which() == 0;
}


then, you'll have to use

Result&lt;int&gt; r = &lt;some function call&gt;;
if ( r.isGood() &amp;&amp; r == 10 )
{
    // Do something with r
}