C++ compile-time checked switch 'statement'
That seems like an awful lot of boilerplate code to replace a single diagnostic that already exists in a lot of compilers. You're replacing

switch (fruit) {
  case APPLE: return "apple"; break;
  case PEAR: return "pear"; break;
  case PLUM: return "plum"; break;
}


with

&lt;at file scope&gt;
NEWSWITCH(uniqueID, std::string);
DEFCASE(uniqueID, APPLE) { return "apple"; }
DEFCASE(uniqueID, PEAR) { return "pear"; }
DEFCASE(uniqueID, PLUM) { return "plum"; }
DEFDEFAULT(uniqueID) { assert(false); }

...
Switch&lt;NumTypes&gt;(uniqueID(), fruit);


The most onerous requirement there is putting all the switch logic at file scope; you can't localize it to the actual codepath where it's going to be used. The second most onerous requirement is coming up with uniqueID, a global identifier which must be different for each switch that you convert using this pattern.

A much better solution to your original problem would be to use an array:

int main() {
    MyType iType = TypeB;

    std::string typenames[NumTypes] = { "TypeA", "TypeB", "TypeC" };

    assert(0 &lt;= (int)iType &amp;&amp; (int)iType &lt; NumTypes);
    std::string zTypeName = typenames[iType];

    std::cout &lt;&lt; "Type name: " &lt;&lt; zTypeName &lt;&lt; std::endl;
}


This code statically enforces that each index in 0..NumTypes-1 is associated with a std::string in the array; and (just like your original code) it dynamically asserts that iType is in the proper range.