You don't want to do this with macros in C++; a function is fine:
char const* num_name(int n, char const* default_=0) {
// you could change the default_ to something else if desired
static char const* names[] = {"Zero", "One", "Two", "..."};
if (0 <= n && n < (sizeof names / sizeof *names)) {
return names[n];
}
return default_;
}
int main() {
cout << num_name(42, "Many") << '\n';
char const* name = num_name(35);
if (!name) { // using the null pointer default_ value as I have above
// name not defined, handle however you like
}
return 0;
}
Similarly, that square should be a function:
inline int square(int n) {
return n * n;
}
(Though in practice square isn't very useful, you'd just multiply directly.)
As a curiosity, though I wouldn't recommend it in this case (the above function is fine), a template meta-programming equivalent would be:
template<unsigned N> // could also be int if desired
struct NumName {
static char const* name(char const* default_=0) { return default_; }
};
#define G(NUM,NAME) \
template<> struct NumName<NUM> { \
static char const* name(char const* default_=0) { return NAME; } \
};
G(0,"Zero")
G(1,"One")
G(2,"Two")
G(3,"Three")
// ...
#undef G
Note that the primary way the TMP example fails is you have to use compile-time constants instead of any int.