2016-08-04 20 views
1

Angenommen, ich Code wie diese:Erhalten Sie Aufzählungstyp von enumerator

#include <cstdio> 

enum Foo { Foo_A, Foo_B }; 
enum Bar { Bar_A, Bar_B }; 

template<typename enumeration, int enumerator> 
struct tpl; 

template<int enumerator> 
struct tpl<Foo, enumerator> 
{ 
    tpl() { printf("Foo: %d\n", enumerator); } 
}; 

template<int enumerator> 
struct tpl<Bar, enumerator> 
{ 
    tpl() { printf("Bar: %d\n", enumerator); } 
}; 

int main() 
{ 
    tpl<Foo, Foo_A> foo_a; 
    tpl<Foo, Foo_B> foo_b; 
    tpl<Bar, Bar_A> bar_a; 
    tpl<Bar, Bar_B> bar_b; 
    return 0; 
}; 

Gibt es eine Möglichkeit, die „Vervielfältigung“ am Einsatzort zu reduzieren? I.e. kann ich den Enumerationstyp "Foo" aus dem Enumerator "Foo_A" etc. nicht ableiten und den im obigen Template-Code irgendwie verwenden? Würde hier eine enum-Klasse helfen?

+2

Dieser Code sieht wie eine Lösung für ein Problem aus. Was ist das Problem? –

Antwort

2

Die Antwort auf Ihre Frage ist, keine gibt es derzeit keine Möglichkeit, dies zu tun. Was Sie vor sich haben, ist als template <typename T, T t> Idiom bekannt. In der Tat, wenn Sie es googeln, werden Sie fast 75.000 Treffer finden, und keine Umgehungslösung. Sie müssen sich spezialisieren, wie Sie es getan haben.


Aber es gibt gute Nachrichten am Horizont. Dies wurde an den Normenausschuss viele Male in den letzten zehn Jahren vorgeschlagen:

  • N3405 Vorgeschlagen, die Zulage von template <typename T t> Wo T die Art und t ist der Wert, nur ein Wert als Vorlage Argument übergeben wird
  • N3601 vorgeschlagen, dass template <typename T, T t> ein spezieller Fall sein, wenn der Compiler nur einen einzigen Wert als Vorlage Argument und das würde ableiten annehmen würde T und t
  • N4469 Vorgeschlagen, dass das Schlüsselwort auto sein, llowed einen Meta-Parameter angeben: template <auto t>, so dass ein Wert als Template-Argument t weitergegeben werden konnte und es
  • abgeleiteten Typ die

Am 4. Mai `15 Treffen in Lenexa, N4469 Traktion schließlich gewonnen durch Ermutigung zu verdienen und den Antrag auf ein Revision in der Standardausschusssitzung: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4539.html#9

Die erste Revision, P0127R0, wurde am 25. September '15 eingereicht.

Eine Nachfolgeversion wurde am 4. März 2016 eingereicht: P0127R1, die Änderungen an den Entwurfsarbeitsabschnitten für Konzepte vorschlägt.

P0127R2 konzentrierte sich auf die vollständige Angabe der Idiomänderung in Nicht-Konzepte-Abschnitten des Arbeitsentwurfs, da unklar ist, ob Konzepte in C++ 17 enthalten sind. http://developerblog.redhat.com/2016/07/13/red-hat-iso-c-standards-meeting-june-2016-core-language/

So mit der Ankunft von C 17 ++ Sie template <typename T, T t> Idiom und die Verwendung der Lage sein, entsorgen Sie das: Diese Revision wurde in den 17 Standard-C++ auf 23. Juni '16 angenommen

template <auto t> 
struct tpl{ 
    tpl(){ cout << typeid(decltype(t)).name() << ": " << t << endl; } 
}; 
+1

Wenn jemand neugierig war, verwendet Visual Studio 'type_info :: raw_name()', um den verfälschten Namen auszugeben, der dem Namen der GCC-Ausgaben für 'type_info :: name()' ähnelt. –

+0

Heißt das, man könnte den Template-Typ überladen, wenn 'f ()' eine andere Funktion aufruft als 'f ()'? –

+1

@JimV Was du redest, ist Spezialisierung (und das ist jetzt möglich.) Diese Frage bezieht sich auf die 'Vorlage ' Idiom. Wobei ich 'tpl '' '' '' '' '' '' '' '' '' '' '' '' '' '' 13 'ist offensichtlich ein' int'. N4469 versucht, es uns zu ermöglichen, 'tpl <13>' aufzurufen und in der Lage zu sein, dies als * both * einen Typ * und * ein Wertvorlagenargument zu verwenden. –