verschachtelte Klassen, templates & friends



  • Hallo,

    der folgende Code kompiliert nicht:

    template <typename T>
    class Q
    {
       public:
          class R
          {
             template <typename U>
             friend bool operator==(const typename Q<U>::R& a, const typename Q<U>::R& b);
          };
    };
    
    template <typename U>
    bool operator==(const typename Q<U>::R& a, const typename Q<U>::R& b)
    {
       return true;
    }
    
    int main()
    {
       Q<int>::R a, b;
       a == b;
    }
    
    21:6: error: invalid operands to binary expression ('Q<int>::R' and 'Q<int>::R')
    13:6: note: candidate template ignored: couldn't infer template argument 'U'
    

    Wie kann ich den Fehler beheben?


  • Mod

    Das funktioniert nicht, weil das Template-Argument in dem nested-name-specifier vorkommt. Das ist ein sog. 'non-deduced context'.

    If a template parameter is used only in non-deduced contexts and is not explicitly specified, template argument deduction fails.
    The non-deduced contexts are:
    — The nested-name-specifier of a type that was specified using a qualified-id.



  • Der kann den Templateparameter U nicht auflösen, weil der nicht genau weiß wie sich die Klassen bei verschiedenen Spezialisierungen verhalten.
    Lösung:

    template <typename T>
    class Q
    {
       public:
          class R
          {
             friend bool operator==(const typename Q<T>::R& a, const typename Q<T>::R& b)
             {
       				return true;
    			}
          };
    };
    

    operator== gehört somit direkt zu R und kann via ADL gefunden werden.



  • Ok, das macht auch irgendwie Sinn. Also ist die einzige Möglichkeit die Funktion direkt in der Klasse zu definieren?


  • Mod

    Ein einfacher Fix dafür ist

    template <typename T>
    struct Q
    {
    	struct R
    	{
    		friend bool operator==(const R& a, const R& b) { return true; }
    	};
    };
    
    int main()
    {
    	Q<int>::R a, b;
    	a == b;
    }
    

    Die Operatorfunktion wird dabei durch ADL gefunden und ist kein Template.

    Edit: Das gibt es gar nicht, da schreibe ich glatt genau was Nathan schon schrieb...



  • Arcoth schrieb:

    Das gibt es gar nicht, da schreibe ich glatt genau was Nathan schon schrieb...

    :p


Log in to reply