问题
C++ doesn't have a way to get the string representation of an enum. People get around this by writing custom functions that contain a lot of boilerplate code akaswitch
with case XYZ return "XYZ";
That of course requires users of the enum to know the name of the custom function.
So I thought I could just add a specialization to std::to_string
to enable a user to use to_string
on my enums. Something like this:
//
#include <iostream>
#include <string>
#include <cassert>
#define TEST
class Car
{
public:
enum class Color
{
Red,
Blue,
White
};
};
#ifdef TEST
#include <string>
namespace std
{
std::string to_string (Car::Color c)
{
switch (c)
{
case Car::Color::Red:
return "Red";
case Car::Color::Blue:
return "Blue";
case Car::Color::White:
return "White";
default:
{
assert(0);
return "";
}
}
}
}
#endif
int main()
{
std::cout << std::to_string(Car::Color::White) << std::endl;
}
Are there any problems with this solution?
回答1:
That's not "overriding" (which applies to virtual
functions), and you haven't added a "specialization" (which applies to templates), you've added an overload, which adds a declaration and definition of a new function to namespace std
and that's forbidden:
17.6.4.2.1 Namespace std [namespace.std]
The behavior of a C++ program is undefined if it adds declarations or definitions to namespacestd
or to a namespace within namespacestd
unless otherwise specified. A program may add a template specialization for any standard library template to namespace std only if the declaration depends on a user-defined type and the specialization meets the standard library requirements for the original template and is not explicitly prohibited.
A better solution would be to overload it in your own namespace, and call to_string(c)
instead of std::to_string(c)
. That will find the right function and you don't need to add anything to std
来源:https://stackoverflow.com/questions/17136497/is-overriding-stdto-string-for-user-defined-enums-the-proper-way-to-provide-to