Class for Value + Error Code This is a class similar to std::pair and std::tuple inspired by Alexandresku's Expected&lt;T&gt;. Let me know if this class can be helpful for simple error handling.

template&lt;class E, class T&gt;
class CheckValue{
public:
    template&lt;class UT&gt;
    CheckValue(const E &amp;e, UT &amp;&amp;t) : e(e), t(std::forward&lt;UT&gt;(t)){}

    operator E() const{
        return e;
    }

    T &amp;get(){
        return t;
    }

    const T &amp;get() const{
        return t;
    }

private:
    E e;
    T t;
};


... and here is some usage. I did usage with bool first, but deliberately redesign it to work with enum class to show full power.

enum class CalcError{
    OK,
    ERROR,
    DIV_BY_ZERO
};

CheckValue&lt;CalcError, float&gt; calc(float a, float b){
    if (b == 0)
        return { CalcError::DIV_BY_ZERO, 0 };

    return { CalcError::OK, a / b };
}

void prn(float a, float b){ 
    switch( auto val = calc(a, b) ){
    case CalcError::DIV_BY_ZERO:
        std::cout &lt;&lt; "Division by zero" &lt;&lt; std::endl;
        break;

    case CalcError::ERROR:
        std::cout &lt;&lt; "Error"        &lt;&lt; std::endl;
        break;

    default:
    case CalcError::OK:
        std::cout &lt;&lt; val.get()      &lt;&lt; std::endl;
        break;
    }
}

int main(){
    prn(5, 2);
    prn(5, 0);
}
The code looks quite good to me in general. Here are a few remarks.

Avoid implicit conversion operators

The implicit conversion operator

template &lt;class E, class T&gt;
CheckValue&lt;E, T&gt;::operator E() const;


might do you more harm than good. In particular, if both E and T are of arithmetic type, forgetting to call get will happily use the error code instead of the value and you'll probably have a bad time tracing down this bug.

Maybe a plain old function would serve you better.

template &lt;class E, class T&gt;
E
CheckValue&lt;E, T&gt;::status() const;


Take sink arguments by-value

It seems to me that you expect E to be some cheaply copyable value type, like an enum or an integer so you can easily afford always making a copy. That's perfectly reasonable but then I'm surprised why you take it by const reference. Just take it by-value instead. If you're not so sure whether it will always be cheap to copy, apply std::move to it instead. It should never cost you anything and might sometimes benefit you.

template &lt;class UT&gt;
CheckValue(E, UT&amp;&amp; t) : e(std::move(e)), t(std::forward&lt;UT&gt;(t)) {}


Of course, you could also decide to take both parameters by forwarding reference, just in case.

template &lt;class UE, class UT&gt;
CheckValue(UE&amp;&amp; e, UT&amp;&amp; t) : e(std::forward&lt;UE&gt;(e)), t(std::forward&lt;UT&gt;(t)) {}


Consider special-casing the “success” case

Currently, your class does not know any semantics about E.  If its intention is to be used as “success or failure” indicator, you could make this explicit. This would also allow you to omit the error code when there actually is no error.

For example, you could add a third template parameter that indicates the “success” value (note that I have re-ordered the parameters).

template &lt;class ValueT, class StatusT, StatusT Good = static_cast&lt;StatusT&gt;(0)&gt;
class CheckValue;


Then you could offer a single-argument constructor

template &lt;class ValueT, class StatusT, StatusT Good&gt;
template &lt;class V&gt;
CheckValue&lt;ValueT, StatusT, Good&gt;::CheckValue(V&amp;&amp; v)
    : e(Good), t(std::forward&lt;V&gt;(v)) {}


and your happy path would be just return 42;.

Note that I have deliberately not marked the single-argument constructor as explicit in this case. Otherwise, you'd have to write return {42};. Which version you prefer is probably a matter of taste.

If your class knows about the distinct “success” case, you can add a check for it.

template &lt;class ValueT, class StatusT, StatusT Good&gt;
explicit
CheckValue::operator bool() const noexcept
{
  return (this-&gt;e == Good);
}


This would allow code like this.

if (const auto cv = prn(5, 2))
    std::cout &lt;&lt; cv.get() &lt;&lt; '\n';
else
    std::cerr &lt;&lt; "error: " &lt;&lt; to_string(cv.status()) &lt;&lt; '\n';


Instead of a single Good value, you could have a more general predicate but this would deprive you of the ability to default it in the lucky case and smells like over-engineering to me.

Think whether you want a “no value” state

If your computation fails, you currently have to pass a dummy value to the constructor because it always initializes the t member. If an object of type T is expensive to construct, this would be wasteful. It also feels bad having to specify a value when you actually have none.  Of course, you also don't want to default-construct the t member in this case as this might be equally costly or not even possible.

The usual way to handle this is to use a properly aligned buffer instead of a typed variable T.

char buffer[sizeof(ValueT)] alignas(ValueT);


In your constructor, you use placement-new to create an object inside the buffer, if you have one.

template &lt;class ValueT, class StatusT, StatusT Good&gt;
template &lt;class V&gt;
CheckValue&lt;ValueT, StatusT, Good&gt;::CheckValue(V&amp;&amp; v) : e(Good)
{
  new (this-&gt;buffer) ValueT(std::forward&lt;V&gt;(v));
}


Your get function would then cast the buffer to a pointer of the appropriate type, after optionally checking that there is a value in it.

template &lt;class ValueT, class StatusT, StatusT Good&gt;
ValueT&amp;
CheckValue&lt;ValueT, StatusT, Good&gt;::get()
{
  assert(this-&gt;e == Good);
  return *reinterpret_cast&lt;ValueT *&gt;(this-&gt;buffer);
}


Don't forget to invoke the destructor, too.

template &lt;class ValueT, class StatusT, StatusT Good&gt;
CheckValue&lt;ValueT, StatusT, Good&gt;::~CheckValue()
{
  if (this-&gt;e == Good)
    reinterpret_cast&lt;ValueT *&gt;(this-&gt;buffer)-&gt;~ValueT();
}


You would remove the two-argument constructor now. In order to construct an object in an error-state, you'll need a static factory function.

template &lt;class ValueT, class StatusT, StatusT Good&gt;
CheckValue&lt;ValueT, StatusT, Good&gt;
CheckValue&lt;ValueT, StatusT, Good&gt;::make_failure(StatusT e)
{
  assert(e != Good);
  CheckValue bad {};  // use private default-constructor
  bad.e = e;
  return bad;
}


The private default constructor does not initialize the object.

template &lt;class ValueT, class StatusT, StatusT Good&gt;
CheckValue&lt;ValueT, StatusT, Good&gt;::CheckValue() noexcept {}


It must never be called without setting e to anything but Good immediately afterwards.  (Or the destructor and the other functions would invoke undefined behavior.)  Therefore, it is essential that this dangerous constructor is private.

You will also need to write custom copy / move constructors and assignment operators. You might want to implement them in terms of a custom swap overload.

Consider restricting the type of the error code

Since the code makes a few assumptions about the type of the error code, you might as well make these explicit and restrict it to POD types. To do this, simply put

static_assert(std::is_pod&lt;StatusT&gt;::value, "Status code must be POD type");


at the top of your class definition.

Apply noexcept where appropriate

If a function has no pre-conditions and cannot fail, declare it as noexcept.

Consider using more descriptive names

Some of your variable names seem overly terse to me. As you could see in the example code I've written above, I'd strongly consider renaming t to value, e to status and so forth.

I also recommend that you establish a convention of naming (private) member variables specially. Personally, I like suffixing them with an underscore (eg value_); others prefer the m_ or M_ prefix (eg m_value). Pick what you like and use it consistently.

Use nouns for type names

An object represents a thing, not an action. A type represents a class of things. Therefore, it is generally accepted that type names should be nouns. In your case, CheckedValue would be preferred instead of CheckValue.