Problemumgehung für Vorlagenargumentabzug im nicht geführten Kontext
-
25-10-2019 - |
Frage
Betrachten Sie den folgenden Code:
#include <iostream>
template<class T>
struct outer {
struct inner {};
};
template<class T>
std::ostream& operator<<(std::ostream & stream,
typename outer<T>::inner const& value) {
std::cout << "An outer::inner!";
return stream;
}
int main() {
outer<float>::inner foo;
std::cout << foo << std::endl; // does not compile
}
Dies kompiliert nicht, weil typename outer<T>::inner
ist ein Nicht deduzierter Kontext (wie erklärt hier) bedeutet, dass der Typ-Argument-Typ nicht vom Compiler abgeleitet werden kann (lesen Diese Antwort für das Warum). Wie ich es sehe, habe ich zwei Möglichkeiten, damit es funktioniert:
- Bewegen
inner
außerhalbouter
und machen Sie es zu einer Klassen-Template. Ich bevorzuge diesen, da die Auswirkungen auf den Verwendungscode kleiner sind. - Füge hinzu ein
to_string
-Method bis innerlich.
Gibt es dafür andere Lösungen (die nicht zu einer hässlichen Syntax im Verwendungscode führen)?
Lösung
Sie können den Bediener in den Körper der inneren Klasse bewegen und setzen friend
bevor. Ersetzen Sie dann den Parametertyp durch Just Just inner
.
Eine andere Technik besteht darin, von einer durch inneren Parametrisierung von CRTP -Basis parametrisierten CRTP -Basis abzuleiten. Machen Sie dann den Parameter -Typ die CRTP -Klasse und geben Sie den Parameterverweis auf die abgeleiteten inner
Klasse, die Art des Arguments von Vorlagen angegeben wird, das Sie ableiten.