Ich möchte feststellen, ob etwas ein Container ist. Im Moment teste ich es an Containern, die einen Typ und einen Zuweiser haben. Mein ultimatives Ziel ist es, zu lernen, wie man eine Containervorlage schreibt, die, wenn sie Layer von sich selbst enthält, eine direkte Iteration ihrer innersten Elemente erlaubt. Z.B. Wenn es einen Container mit 3 Containern gibt, von denen jeder 3 weitere Container enthält, von denen jeder 3 Elemente enthält, möchte ich in der Lage sein, alle 27 Elemente in einem Bereich basierend auf der Schleife zu durchlaufen. Unterscheidend, ob etwas ein Container ist, der direkt Elemente enthält oder Container von Elementen (oder Containern von Containern ... von Containern von Elementen enthält), die SFINAE verwenden, um zu überprüfen, ob das Element einen Iterator hat, scheint ein logischer erster Schritt in Richtung der begin()
Funktion zu sein sollte den Iterator an das Element oder das Ergebnis der begin()
Funktion dieses Elements zurückgeben. Wenn ich meinen ersten Schritt arbeiten kann, würde Ich mag diese Logik enthalten in meinem Container zu schreiben, aber ich kann es nicht kompilieren erhalten:Wie kann man feststellen, ob etwas ein Container ist?
#include <vector>
#include <iostream>
template <typename T,
template <typename E, typename Allocator = std::allocator<E>> class Container
>
void is_cont(typename Container<T>::iterator it)
{
std::cout << "is iterator\n";
}
template <typename T,
template <typename E, typename Allocator = std::allocator<E>> class Container
>
void is_cont(Container<T>& cont)
{
std::cout << "is container\n";
}
int main()
{
std::vector<int> vec{ 2, 4, 6 };
is_cont(vec); // Output: "is container"
//is_cont(vec.begin()); // COMPILER ERROR
}
Wie kann ich dieses Problem beheben?
der Iterator Bei 'vec.begin()' (was recht ist wahrscheinlich ist es nur ein 'int *'), es gibt keine Möglichkeit, dass der Compiler jede mögliche Container-Klasse instanziieren kann, um zu sehen, ob dieser Iterator zufällig vom Typ Container :: iterator ist. Und selbst wenn es möglich wäre, wäre es wahrscheinlich mehrdeutig. Sie müssten die Template-Parameter für die Funktion explizit angeben. –
Kundor
@Kundor Wenn 'vec.begin()' ein 'int *' ist, wäre da noch ein 'std :: vector :: iterator', mit dem Unterschied, dass es ein' typedef' für 'int * ist '? Es scheint die Zeile 'std :: vector vec {2, 4, 6} zu ersetzen;' mit 'std :: vector vec (3, Balken {});' wo 'Bar' ein leerer Dummy' struct' ist der gleiche Fehler. –
CodeBricks
Ja. Damit? Bei einem Funktionsaufruf 'is_cont (int *)' soll der Compiler die Template-Parameter ableiten. Sie fragen also, dass Sie rückwärts von 'int *' arbeiten, um einen Typ mit einem Member typedef 'iterator' zu finden, der' int * 'ist. Sicherlich können Sie sehen, dass dies nicht funktionieren kann (zum einen, da dies Vorlagenklassen sind, gibt es buchstäblich unendliche Möglichkeiten, die es untersuchen müsste). – Kundor