Function outcome: consistent approach and easy logging
Is this a working program? In other words, have you tried to compile this? I'd be very surprised it compiled.

#include &lt;hash_map&gt;

This header does not exist in the C++ Standard Library. If you want a hash map, you need to use #include &lt;unordered_map&gt; and use the C++11 standard.

typedef const CStatus Status;

I'm pretty sure that something like: const Status S_SUCCESS doesn't compile as that resolves to: const const CStatus S_SUCCESS. 

#ifndef S_SUCCESS
#define S_SUCCESS CStatus::CS_SUCCESS
#endif // S_SUCCESS

#ifndef S_UNDEFINED_ERROR
#define S_UNDEFINED_ERROR CStatus::CS_UNDEFINED_ERROR
#endif // S_SUCCESS


You have an error in the comment for the S_UNDEFINED_ERROR macro.

Your RegisterState function could also be slightly simplified:

// Static Functions 
static Status registerState(const tstring &amp;stateMsg)
{
    // Post: 
    auto res = states.emplace({nextState + 1, stateMsg});

    // if state has been inserted
    return res.second ? Status(++nextState) : Status(res.first-&gt;first);
}

const tstring&amp; toString() const 
{
    return (states.find(state) == states.end()) ? states[state] : _T("Undefined");
}


I'm not familiar with what a tstring is but this function should be marked static (as only static members can access static member variables) and you shouldn't be returning the string by const value. Let the caller decide whether or not they want to make it const. 

operator tstring() const
{
    return toString();
}

operator int() const
{
    return state;
}


What is the point of these and what do they return? These should be removed as they aren't going to be useful to your API. The entire point of your API is to allow the user to easily create new States without having them know too many of the internal implementation details.

bool operator!=(const CStatus&amp; obj) const
{
    return state != obj.state;
}


Implement this in terms of operator==():

bool operator!=(const CStatus &amp;ob) const
{
    return !(state == obj.state);
}


Finally, with this setup, your user will not be able to add any states during compile time. They will only be able to add checks during runtime (most likely during program startup). You should change your description to reflect this.