ExitCode class and derived Status class able to return a value I was thinking about an ExitCode concept in a strict nothrow environment and came up with the following two classes and would like to get some peer review on what flaws they have.
They are very simple in terms of inner complexity but are quite complicated in terms of language features (at least for me :) )

ExitCode is a class encapsulating an arbitrary state and a status message.

#include &lt;string&gt;

class ExitCode
{
public:
    enum class TState
    {
        OK,
        FAILED,
        CORRECTED
    };


    /**
    * Default failing exit code, can be created from a simple string
    */
    ExitCode(const std::string&amp; msg = "", const TState state = TState::FAILED)
        : m_sMessage(msg), m_state(state)
    {
    }

    ExitCode(const TState state) : m_state(state)
    {
    }

    /**
    * Uses nested exit code message and adds it to the outer message
    */
    ExitCode(const std::string&amp; msg, const TState state, const ExitCode&amp; nested) :
        m_sMessage(msg + ": " + nested.m_sMessage), m_state(state)
    {
    }

    ExitCode(ExitCode&amp;&amp; other) // Note: VS 2012 has no noexcept
    {
        m_state = other.m_state;
        m_sMessage = std::move(other.m_sMessage);
    }

    ExitCode&amp; operator=(ExitCode&amp;&amp; other) // Note: VS 2012 has no noexcept
    {
        if (this != &amp;other)
        {
            m_state = other.m_state;
            m_sMessage = std::move(other.m_sMessage);
        }

        return *this;
    }

    const std::string&amp; GetMessage() const
    {
        return m_sMessage;
    }

    TState GetState() const
    {
        return m_state;
    }

private:

    std::string m_sMessage;
    TState m_state;
};


Simple cases could be

ExitCode foo1("All failed");

ExitCode foo2("All good", ExitCode::TState::OK);

ExitCode root("All good, but was", ExitCode::TState::OK, foo);




And a derived Status&lt;T&gt; class which is also able to provide some return value. The idea is that some method X may or may not return a valid output but at the same time may or may not return an error (which should not be propagated via exceptions)

template &lt;typename TResult&gt;
class Status : public ExitCode
{
public:

    // Converting
    Status( const TResult&amp; result, const std::string &amp; msg = "", const TState state = TState::OK ) 
        : ExitCode( msg, state ), m_result( result )
    {
    }

    // Converting move
    Status( TResult&amp;&amp; result, const std::string &amp; msg = "", const TState state = TState::OK )
        : ExitCode( msg, state ), m_result( std::move( result ) )
    {
    }

    // Converting
    Status( const std::string&amp; msg = "", const TState state = TState::FAILED ) 
        : ExitCode( msg, state )
    {
    }


    TResult&amp; GetResult() const
    {
        return m_result;
    }

private:

    TResult m_result;
};


Some usage could be

Status&lt;int&gt; s1 = 23;

Status&lt;int&gt; corrected( 1, "Failed to produce valid output, but corrected something", ExitCode::TState::CORRECTED );

Status&lt;int&gt; s2 = "This was bad";




Are there any obvious bad design decisions in such an implementation?

I am currently aware of one: Multiple implicit string conversion when I write code like that:

Status&lt;std::string&gt; status = "Which constructor to use?";
Overall I would say this is good code. Still, there are a few things that you should (or, at least, could) improve:


TResult&amp; GetResult() const is a bug. This should read TResult const&amp; GetResult() const (and if you had done more testing, your compiler likely should have told you). 
You are missing an include (#include &lt;utility&gt;) for std::move.
Depending on how you intend to use these classes, you should add a virtual destructor to ExitCode. The reason is that, if you do fancy polymorphism and try to delete an instance of Status through a pointer to ExitCode, you get undefined behavior. If you don't care about the possible polymorphism, you should be fine as-is.
I share your worry about implicit conversions. I would consider making your constructors explicit.
Keep your formatting consistent. Although your formatting is almost always the same, there is one place where you diverge from it, namely const std::string &amp; msg = "" in the first two constructors of Status. Why do you have a space between std::string and &amp;? (I suppose it's just some oversight of yours).
Why is the default value to two of the constructors of Status for the parameter state TState::OK, but the last constructor has TState::FAILED instead? This is very likely to cause confusion.