用于任意和可变深度的嵌套列表的正确 C++ 类型?

Tho*_*son 6 c++ python types list

我正在尝试将一些代码从 Python 移植到 C++。Python 代码有一个函数foo可以采用具有可变列表深度的嵌套整数列表。例如,这些是对 foo 的合法函数调用:

foo([ [], [[]], [ [], [[]] ] ])
foo([1])
foo([ [1], [2, 3, [4, 5]], [ [6], [7, [8, 9], 10] ] ])
Run Code Online (Sandbox Code Playgroud)

对于可以接受此类参数的 C++ 方法,方法签名应该是什么?

Art*_*yer 4

这是一种定义和使用非常简单的方法:

#include <variant>
#include <vector>

struct VariableDepthList : std::variant<std::vector<VariableDepthList>, int> {
private:
    using base = std::variant<std::vector<VariableDepthList>, int>;
public:
    using base::base;
    VariableDepthList(std::initializer_list<VariableDepthList> v) : base(v) {}
};
Run Code Online (Sandbox Code Playgroud)

这是基于这样的事实:您的类型是一个int或一个列表(相同类型),添加一个initializer_list构造函数只是为了便于使用。

您可能也想添加一些辅助函数,例如is_vector()/ is_value()

这是一个使用它的示例:

#include <iostream>

void foo(const VariableDepthList& v) {
    // Use like a variant. This is a print function
    if (auto* as_vector = std::get_if<std::vector<VariableDepthList>>(&v)) {
        if (as_vector->empty()) {
            std::cout << "[]";
            return;
        }
        std::cout << "[ ";
        bool first = true;
        for (const auto& el : *as_vector) {
            if (!first) {
                std::cout << ", ";
            }
            first = false;

            foo(el);
        }
        std::cout << " ]";
    } else {
        auto* as_int = std::get_if<int>(&v);
        std::cout << *as_int;
    }
}

int main() {
    foo({});
    std::cout << '\n';
    foo({ 1 });
    std::cout << '\n';
    foo({ {}, {{}}, { {}, {{}} } });
    foo( {{1},{2,3,{4,5}},{{6},{7,{8,9},10}}} );
    std::cout << '\n';
}
Run Code Online (Sandbox Code Playgroud)