2017-12-06 8 views
-1

Ist es möglich, eine Klassenmethode für einzelne Enum-Werte zu spezialisieren? Insbesondere habe ich eine Enum und eine Klasse wie folgt:Template-Spezialisierung für Enum-Werte

#include <iostream> 
#include <stdio.h> 

using namespace std; 

enum class Animal { dog, cat, bird }; 
class Sound 
{ 
    public: 
     static void getSound (const Animal& arg) 
     { 
     switch (arg) 
     { 
      case Animal::dog: 
      // dog specific processing 
      break; 

      case Animal::cat: 
      // cat specific processing 
      break; 

      case Animal::bird: 
      // bird specific processing 
      break; 

      default: 
      return; 
     } 
     } 
}; 

Ich möchte getSound Funktion spezialisiert für jede der ENUM-Werte, um loszuwerden des Schaltergehäuses. Ist eine solche Template-Spezialisierung möglich?

Antwort

1

Ja, es ist möglich. Sehen Sie sich das Beispiel unten an.

#include <iostream> 
#include <stdio.h> 

using namespace std; 

enum class Animal { dog, cat, bird }; 
class Sound 
{ 
    public: 
     template<Animal animal> 
     static void getSound(); 
}; 

template<> 
void Sound::getSound<Animal::dog>() 
{ 
    // dog specific processing 
} 

template<> 
void Sound::getSound<Animal::cat>() 
{ 
    // cat specific processing 
} 

template<> 
void Sound::getSound<Animal::bird>() 
{ 
    // bird specific processing 
} 

int main() 
{ 
    Sound::getSound<Animal::dog>(); 
} 
+0

Danke S.M. für deine Antwort. Dies löst meine Abfrage. Akzeptieren Sie es als Antwort. – vchandra

2

Ich sehe nicht, warum Sie für die Spezialisierung gehen möchten. Wenn dieses Beispiel anzeigt und Ihre enumnerators sind sequentielle und ausgehend von 0, können Sie nur eine Lookup-Tabelle verwenden:

enum class Animal { dog, cat, bird, count = (bird - dog + 1) }; 

static std::string getSound (Animal arg) // Pass an enumeration by value, it's cheaper 
{ 
    std::array<char const *, static_cast<std::size_t>(Animal::count)> const sound {{ 
    "bark", "meow", "chirp" 
    }}; 
    return sound.at(static_cast<std::size_t>(arg)); 
} 

Und das ist es. Es ersetzt auch die Zeichenfolge "unknown", indem eine Ausnahme ausgelöst wird. Ich denke, dies ist gerechtfertigt, da eine begrenzte Aufzählung impliziert, dass wir eine strenge Überprüfung des übergebenen Wertes erwarten. Und brechen, dass eine außergewöhnliche Situation ist.


Auch Ihre editierten Frage kann zu einer Lookup-Tabelle unterzogen werden:

static void getSound (Animal arg) // Pass an enumeration by value, it's cheaper 
{ 
    std::array<std::function<void(void)>, 
      static_cast<std::size_t>(Animal::count)> const handler{{ 
    [] { /*Process for dog*/ }, 
    [] { /*Process for cat*/ }, 
    [] { /*Process for bird*/ } 
    }}; 
    handler.at(static_cast<std::size_t>(arg))(); // The last() is invocation 
} 
+0

Vielen Dank für Ihre Antwort. Dies war nur ein anschauliches Beispiel. Es gibt eine Reihe von Verarbeitungsprozessen innerhalb des Gehäuses. Deshalb wollen wir Spezialisierung nutzen. Ich habe die Frage bearbeitet, um dies zu reflektieren. – vchandra

+0

@vchandra - Das disqualifiziert eine Nachschlagetabelle immer noch nicht. Warte eine Sekunde – StoryTeller

+0

Entschuldigung für meine späte Antwort. Und vielen Dank, dass Sie sich die Zeit genommen haben, mir verschiedene Lösungen anzubieten. Ich habe aus dieser Antwort einiges gelernt. Ich akzeptiere die Antwort von S.M. wie es näher an meiner ursprünglichen Frage um Template-Spezialisierung. Danke noch einmal. – vchandra

Verwandte Themen