template parameter is not of integral or enumeration type



  • Moin,
    ich versuche mich gerade in templates einzuarbeiten und ich würde für dieses Beispiel gerne die Syntax in Zeile 12 verwenden. Leider kriege ich nicht raus, wie ich Zeile 3 schreiben muss, damit es klappt:

    error: template parameter ‘seq’ of type ‘const string& {aka const std::basic_string<char>&}’ is not allowed in an integral constant expression because it is not of integral or enumeration type
    

    Der Fehler-Meldung entnehme ich, dass man sowas nicht mit strings (oder sonstige not-integrals) machen kann oder übersehe ich was?

    #include <string>
    
    template<typename std::string seq, int n>
    struct isPalindrome
    {
        enum { value = n < 2 ? true : seq[0] == seq[n-1] && isPalindrome<seq.substr(1, n-2),n-2>::value };
    };
    
    int main()
    {
        std::string seq = "reliefpfeiler";
        std::cout << isPalindrome<seq, seq.length()>::value << '\n';
    }
    

  • Mod

    Was soll denn der Sinn der Sache sein? Wie man Palindrome findet oder wie man Palindorme mittels Template-Metaprogrammierung finden könnte? Letzteres wird recht eklig.


  • Mod

    Letzteres wird recht eklig.

    Kommt auf den Sprachstandard an.



  • Moin Moin,

    itsame schrieb:

    Der Fehler-Meldung entnehme ich, dass man sowas nicht mit strings (oder sonstige not-integrals) machen kann oder übersehe ich was?

    richtig, template Parameter können Typen, Templates und einige Konstanten sein. Ein Zeiger auf std::string oder ein String literal wäre möglich, würde Dir aber in Deinem Fall auch nicht weiter helfen, weil Du den Text zur compile Zeit nicht ausgewertet bekommst.

    Du müsstest den String als einzelne Zeichen in einen Typen wrappen und dann als Typliste (z.b. boost::mpl::vector) packen. Dann könntest Du zur compile Zeit feststellen, ob der Text eine Palindrom ist.

    mfg Torsten



  • Torsten Robitzki schrieb:

    Du müsstest den String als einzelne Zeichen in einen Typen wrappen und dann als Typliste (z.b. boost::mpl::vector) packen. Dann könntest Du zur compile Zeit feststellen, ob der Text eine Palindrom ist.

    Das ist die C++98-Lösung. In C++11 würde man variadic templates und einen const char* als Parameter benützen und in C++14 ist es möglich, eine constexpr_string-Klasse als Template-Argument zu übergeben.


  • Mod

    sprachstandard schrieb:

    in C++14 ist es möglich, eine constexpr_string-Klasse als Template-Argument zu übergeben.

    Wenn du Objekte meinst: Falsch.

    N4140 (C++14 IS/FD) [temp.param]/4 schrieb:

    A non-type template-parameter shall have one of the following (optionally cv-qualified) types:

    • integral or enumeration type,
    • pointer to object or pointer to function,
    • lvalue reference to object or lvalue reference to function,
    • pointer to member,
    • std::nullptr_t .

    Wenn du den Typ meinst, macht dein Beitrag keinen Sinn. U.a. weil constexpr nicht Teil von Typen ist.

    In C++11 würde man variadic templates und einen const char* als Parameter benützen

    Nö, letzteres wäre die C++03 Lösung. (Und wie man beides kombinieren soll wäre mir schleierhaft - Indexlisten?) In C++11 geht's mit rekursiven constexpr Funktionen. Und in C++14 mit Schleifen in den constexpr Funktionen.



  • Arcoth schrieb:

    In C++11 würde man variadic templates und einen const char* als Parameter benützen

    Nö, letzteres wäre die C++03 Lösung.

    Variadic Templates in C++03? Haste da nicht was verwechselt?


  • Mod

    hustbaer schrieb:

    Arcoth schrieb:

    In C++11 würde man variadic templates und einen const char als Parameter benützen*

    Nö, letzteres wäre die C++03 Lösung.

    Variadic Templates in C++03? Haste da nicht was verwechselt?

    😕



  • Acho so.
    In dem Satz steht "und", daher dachte ich dass du "letzteres" auf den ganzen Satz beziehst.
    OK, jetzt verstehe ich was du meinst.


  • Mod

    hustbaer schrieb:

    In dem Satz steht "und", daher dachte ich dass du "letzteres" auf den ganzen Satz beziehst.

    Ich hatte schon befürchtet dass jemand darauf anspringt. Macht auch Sinn, daher: Mea culpa.


Anmelden zum Antworten