用现代C++写一个python的简易型list

发布时间 2023-09-08 21:20:15作者: ChebyshevTST

std::variant介绍:en.cppreference.com/w/cpp/utility/variant

 

  通过泛型模板(仅提供了int, double, string三种类型的存储),实现了append, pop, front, back, size等方法,并且通过重载运算符实现了对负数索引的访问。

#include <iostream>
#include <vector>
#include <variant>
#include <string>

class PythonList {
    public:
        template <class T>
        void append(const T& item) {
            v.push_back(item);
        }

        void pop() {
            v.pop_back();
        }

        template <class T>
        T& front() const {
            return std::get<T>(v.front());
        }

        template <class T>
        T& back() const {
            return std::get<T>(v.back());
        }

        std::size_t size() const {
            return v.size();
        }

        std::variant<int, double, std::string> operator[] (int index) const {
            if (index >= 0)
                return v[index];
            std::size_t n{v.size()};
            return v[n + index];
        }

    private:
        std::vector<std::variant<int, double, std::string>> v;
};

int main() {
    PythonList lst;
    lst.append(1);
    lst.append(3.14);
    lst.append("Hello World");

    int n = lst.size();
    for (int i{}; i < n; ++i) {
        if (std::holds_alternative<int>(lst[i]))
            std::cout << "Type: int\n";
        else if (std::holds_alternative<double>(lst[i]))
            std::cout << "Type: double\n";
        else if (std::holds_alternative<std::string>(lst[i]))
            std::cout << "Type: string\n";
    }

    for (int i{-1}; i >= -3; --i) {
        if (std::holds_alternative<int>(lst[i]))
        std::cout << "Type: int\n";
        else if (std::holds_alternative<double>(lst[i]))
            std::cout << "Type: double\n";
        else if (std::holds_alternative<std::string>(lst[i]))
            std::cout << "Type: string\n";
    }
}

  如果不用variant,也可以通过union来实现不同类型的存储,variant可以视作为现代C++的union,并且能实现自动析构。