C++: Funktion schreiben, die beliebigen STL-Container als Argument akzeptiert

English Deutsch

STL-Container nehmen zwei Template-Argumente: den Typ T innerhalb des Containers und den Allokator (der standardmäßig std::allocator<T> ist).

Um also eine Funktion zu schreiben, die einen beliebigen STL-ähnlichen Container akzeptiert, müssen Sie es wie in dieser Beispielfunktion tun:

container_template.cpp
/**
 * Konvertiert einen beliebigen STL-ähnlichen Container in einen std::vector.
 */
template<template<typename, typename> typename Container, typename T, typename Allocator>
std::vector ToVector(const Container<T, Allocator>& args) {
    std::vector ret;
    ret.reserve(args.size());
    for(const T& arg : args) {
        ret.push_back(arg);
    }
    return ret;
}

Diese Funktion kann jeden STL-ähnlichen Container wie std::list, std::vector sowie STL-kompatible Container aus Drittanbieter-Bibliotheken akzeptieren und in einen std::vector konvertieren.

Vollständiges Beispiel:

container_example.cpp
#include <list> // std::list
#include <vector> // std::vector
#include <iostream> // std::cout, std::endl

using namespace std;

/**
 * Konvertiert einen beliebigen STL-ähnlichen Container in einen std::vector.
 */
template<template<typename, typename> typename Container, typename T, typename Allocator>
std::vector ToVector(const Container<T, Allocator>& args) {
    std::vector ret;
    ret.reserve(args.size());
    for(const T& arg : args) {
        ret.push_back(arg);
    }
    return ret;
}

int main() {
    // Liste erstellen
    list myList;
    myList.push_back(2);
    myList.push_back(3);
    myList.push_back(5);
    // In Vektor konvertieren
    vector myVector = ToVector(myList);
    // Vektor ausgeben - sollte 2, 3 & 5 ausgeben
    for(int val : myVector) {
        cout << val << endl;
    }
}

Dank an Jesse Good auf StackOverflow für die Veröffentlichung von Hinweisen zur Lösung dieses Problems. Seine Version funktioniert jedoch nur mit STL-Containern, die std::allocator verwenden, und nicht mit STL-Containern mit benutzerdefinierten Allokatoren. Meiner Erfahrung nach ist es sehr selten, dass man einen benutzerdefinierten Allokator verwenden muss, aber wenn man es tut, ist es sehr schwer zu debuggen, warum das Template nicht übereinstimmt.


Check out similar posts by category: C/C++