Stringliteral als Template-Parameter
-
Hoi,
was ist denn im Moment die gängigste Methode die Limitierung bezüglich von Stringliteralen als Template-Parameter zu umgehen?Ich habe ein Funktionstemplate das ich mit bestimmten Parametern einer Scriptsprache zugänglich mache und ich würde gerne zu Debug-Zwecken den exportierten Namen innerhalb der Funktion haben. An der Funktionssignatur kann ich leider nichts ändern.
So in etwa:
template<Action A, char const* Name> void GenericScriptFunction(ScriptContext* c) { if(InvalidArguments(c)) std::cout << Name << " failed because of invalid parameters !"; foo(c); } ... ScriptEngine::register("Saufen", &GenericScriptFunction<Action::Saufen, "Saufen">); ScriptEngine::register("Rauchen", &GenericScriptFunction<Action::Rauchen, "Rauchen">);
Nur eben in funktionierend.
Danke und Grüße,
Ethon
-
Ich glaube nicht, dass es dafür eine wirklich gängige Methode gibt. In jdem Fall muss der String irgendwie in einzelne Zeichen aufgebrochen werden. boost arbeitet dabei gerne mit Multibyte-Zeichen.
Und Sone wird bestimmt gleich ein Makro dafür hervorkramen.
-
Umständlicher Workaround ohne char...-Hacks:
template <typename T> void f(int i) { std::cout << T::str << ": " << i << '\n'; } struct saufen_data { static constexpr char str[] = "Saufen"; }; constexpr char saufen_data::str[]; int main() { void (*funktionszeiger)(int) = f<saufen_data>; funktionszeiger(0); }
Die bevorzugte Lösung wäre wohl auf C++14 zu warten.
-
camper schrieb:
In jdem Fall muss der String irgendwie in einzelne Zeichen aufgebrochen werden.
Kann umgangen werden, wenn der String in einem Typ versteckt wird.
-
Danke schon mal. Bin (natürlich erst nach dem Posten...) auf boost::mpl::string gestoßen ... sieht nun etwa so aus:
template<Action A, int... NameChars> void GenericScriptFunction(ScriptContext* c) { typedef boost::mpl::string<NameChars...> MplName; if(InvalidArguments(c)) std::cout << boost::mpl::c_str<MplName>::value << " failed because of invalid parameters !"; foo(c); } ... ScriptEngine::register("Saufen", &GenericScriptFunction<Action::Saufen, 'Sauf', 'en'>); ScriptEngine::register("Rauchen", &GenericScriptFunction<Action::Rauchen, 'Rauc', 'hen'>);
Hässlich aber funktionierend...
-
Hab ich kürzlich auch gebraucht, hab den Code grade nicht zur Hand ich glaube die Lösung war wie folgt:
template<Action A, char const** Name> void GenericScriptFunction(ScriptContext* c) { ... } static const char* SaufenString = "Saufen"; ScriptEngine::register("Saufen", &GenericScriptFunction<Action::Saufen, &SaufenString>);