Initialisierung von char* via template gibt Warnung [gelöst]



  • Hi,

    ich habe folgenden Code:

    #include <iostream>
    #include <type_traits>
    
    struct char_test
    {
      // initialize const char*
      char_test(const char s[])
        : str(s)
      {}
    
      const char* str;
    };
    
    template < class T, class Enabled = void >
    struct template_test;
    
    template < class T >
    struct template_test<T, typename std::enable_if< !std::is_same<T, char*>::value >::type >
    {
      // initialize any type except char*
      explicit template_test(const T &t) : value(t) {}
      const T value;
    };
    
    template < class T >
    struct template_test<T, typename std::enable_if< std::is_same<T, char*>::value >::type >
    {
      // initialize char*
      explicit template_test(const char s[]) : str(s) {}
      const T str;
    };
    
    int main()
    {
        char_test c1("baba");
        template_test<char*>c2("baba");
        template_test<int> i1(7);
    
        std::cout << "c1: " << c1.str << '\n';
        std::cout << "c2: " << c2.str << '\n';
        std::cout << "i1: " << i1.value << '\n';
        return 0;
    }
    

    Beim kompilieren (gcc 5.1 c++14) gibt's es für die template Variante mit char* folgende Warnung:

    main.cpp: In instantiation of ‘template_test<T, typename std::enable_if<std::is_same<T, char*>::value>::type>::template_test(const char*) [with T = char*; typename std::enable_if<std::is_same<T, char*>::value>::type = void]’:
    main.cpp:37:37:   required from here
    main.cpp:29:49: warning: invalid conversion from ‘const char*’ to ‘char*’ [-fpermissive]
       explicit template_test(const char s[]) : str(s) {}
    

    Der Nicht-Template Code kompiliert ohne Warnung. Obwohl (meiner Meinung nach) die gleiche Klasse erzeugt wird.

    Hat hier jemand vielleicht eine Erklärung für mich?

    Besten Dank!



  • Stringliterale sind vom Typ const char[] (array mit konstantem inhalt). Dein const T in template_test wird bei T=char* zu char* const (konstanter zeiger, aber das worauf er zeigt ist es nicht).
    Statt deinem std::enable_if gewurschtel kannst du auch einfach template_test auf const char* spezialisieren.



  • Ok, habe ich verstanden. Danke für die Antwort.

    Da ich für den char* Typ noch einen weiteren Parameter im Konstruktor übergeben möchte, konnte ich keine Template Spezialisierung machen. Deswegen das enable_if geschwurbel 😉

    Werde es aber entsprechend anpassen.


Anmelden zum Antworten