2013-06-16 15 views
16

C++ nie ma sposobu na uzyskanie reprezentacji łańcuchowej wyliczenia. Ludzie to obejść poprzez pisanie własnych funkcji, które zawierają dużo kodu boilerplate aka
switch z case XYZ return "XYZ";Czy przesłanianie std :: to_string dla zdefiniowanych przez użytkownika wylicza właściwy sposób dostarczania to_string dla zdefiniowanych przez użytkownika wyliczeń?

To oczywiście wymaga użytkownikom wyliczenia znać nazwę funkcji niestandardowej.

Więc pomyślałem, że mogę dodać specjalizację do std::to_string, aby umożliwić użytkownikowi korzystanie z to_string w moich podsumowaniach. Coś takiego:

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

} 

Czy są jakieś problemy z tym rozwiązaniem?

+4

Nie sądzę, że przeładowywanie funkcji standardowych jest dozwolone, a jedynie specjalizowane szablony. – chris

+0

Dwie rzeczy: chciałbym sprawdzić użycie '#define str (x) # x' (i związanego z nim' #define klej (a, b) a ## b'), aby sprawdzić, czy pasuje do twoich potrzeb z mniejszą tabelą . Po prostu zapnij go w funkcji bezpieczeństwa typu i "# undef" zaraz po zakończeniu. Po drugie, a co mniej ważne, zapomniałeś o 'przełamaniu 'w swoim przełączniku - prawdopodobnie dając powód, by nie używać go, jeśli nie czujesz się super-drażliwy. – FizzixNerd

Odpowiedz

22

To nie jest "nadpisywanie" (co dotyczy funkcji virtual), a nie dodano "specjalizacji" (która dotyczy szablonów), dodano przeciążenie, które dodaje deklarację i definicję nowego funkcja do przestrzeni nazw std i to zabronione:

17.6.4.2.1 namespace std [namespace.std]
zachowanie C++ programu jest niezdefiniowana jeśli dodaje deklaracji lub definicji do przestrzeni nazw std lub do przestrzeń nazw w obrębie przestrzeni nazw std, chyba że określono inaczej. Program może dodać specjalizację szablonu dla dowolnego standardowego szablonu biblioteki do przestrzeni nazw standardowej tylko wtedy, gdy deklaracja zależy od typu zdefiniowanego przez użytkownika, a specjalizacja spełnia standardowe wymagania biblioteki dla oryginalnego szablonu i nie jest wyraźnie zabroniona.

Lepszym rozwiązaniem byłoby przeciążać go we własnej przestrzeni nazw, i nazywają to_string(c) zamiast std::to_string(c). To znajdzie odpowiednią funkcję i nie musisz dodawać niczego do std

+0

czekaj, jestem zdezorientowany, jak masz na myśli "co dodaje deklarację i definicję nowej funkcji do przestrzeni nazw std" ... to_string istnieje w standardzie, prawda? czy uważasz params za część funkcji, dlatego właśnie nazywasz to nowym? – NoSenseEtAl

+0

Tak, to nowa funkcja, prawda? Nie było go wcześniej. To nie jest nowy _name_, ale definiujesz nową funkcję. Funkcja 'std :: to_string (int)' jest inną funkcją do 'std :: to_string (double)' i inną funkcją do 'std :: to_string (Car :: Color)' –

+3

Standard C++ uwzględnia część typów parametrów tej funkcji, to nie tylko ja: ** 1.3.17 [defns.signature] podpis ** nazwa, lista typów parametrów (8.3.5) i otaczająca przestrzeń nazw (jeśli istnieją) –

Powiązane problemy