Подтвердить что ты не робот

Переопределяет std:: to_string для определенных пользователем перечислений надлежащим образом, чтобы предоставить to_string для пользовательских перечислений?

У С++ нет способа получить строковое представление перечисления. Люди обойти это, написав пользовательские функции, которые содержат много шаблонов кода, а также   switch с case XYZ return "XYZ";

Это, конечно, требует, чтобы пользователи перечисления знали имя настраиваемой функции.

Поэтому я подумал, что могу просто добавить специализацию в std::to_string, чтобы позволить пользователю использовать to_string в моих перечислениях. Что-то вроде этого:

//
#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;

}

Есть ли проблемы с этим решением?

4b9b3361

Ответ 1

Это не "переопределение" (применимое к функциям virtual), и вы не добавили "специализацию" (применительно к шаблонам), вы добавили перегрузку, которая добавляет объявление и определение новая функция в пространство имен std, и это запрещено:

17.6.4.2.1 Пространство имен std [namespace.std]
Поведение программы на С++ undefined, если оно добавляет объявления или определения в пространство имен std или в пространство имен в пространстве имен std, если не указано иное. Программа может добавить специализацию шаблона для любого стандартного шаблона библиотеки в пространство имен std только в том случае, если объявление зависит от пользовательского типа, а специализация соответствует стандартным требованиям библиотеки для исходного шаблона и явно не запрещена.

Лучшим решением было бы перегрузить его в вашем собственном пространстве имен и вызвать to_string(c) вместо std::to_string(c). Это найдет нужную функцию, и вам не нужно ничего добавлять к std