模板化多堆栈实现-怎么样?

时间:2020-04-19 05:25:23

标签: c++ containers c++-standard-library

我需要一个“ MultiStack”来容纳不同类型的对象,并将每种类型放在单独的堆栈中。

这是到目前为止的样子。开放的问题是:如何处理多个不同T的容器

class MultiStack
{

public:

    template<typename T>
    const T& Get()
    {
        return Container<T>.back();
    }

    template<typename T>
    void Push( const T& t )
    {
        Container<T>.push_back( t );
    }

    template<typename T>
    void Pop( const T& /*t*/ )
    {
        Container<T>.pop_back();
    }

private:

    // this does not make sense, we obv. need one stack for each T
    // template<typename T>
    // std::vector<T>           Container;

};

现在,我可以使用旧的技巧,将Container置于成员函数中,例如

template<typename T>
auto GetContainer()
{
    static std::vector<T> C;
    return C;
}

但是在多线程时代,我不再喜欢这样。是“危险”,对!!

有没有更好,更优雅的方式?可以想象的是,如果有帮助的话,我会事先知道允许的类型。

1 个答案:

答案 0 :(得分:1)

但是在多线程时代,我不再喜欢这样。是“危险”,对!!

问题不是多线程的。初始化就可以了。 不过,您仍然必须像常规的多线程代码一样保护/同步访问。

问题是容器不是每个MultiTask实例,因为它是静态的。 大多数情况下,好像MultiTask是一个Singleton。

可以想象的是,如果有帮助的话,我会事先知道允许的类型。

这很有帮助,然后您可以使用std::tuple,类似于(C ++ 14):

template <typename ... Ts>
class MultiStack
{
public:
    template<typename T>
    const T& Get() const
    {
        return GetContainer<T>().back();
    }

    template<typename T>
    void Push(const T& t)
    {
        GetContainer<T>().push_back(t);
    }

    template <typename T>
    void Pop()
    {
        GetContainer<T>().pop_back();
    }

private:
    template <typename T>
    const std::vector<T>& GetContainer() const { return std::get<std::vector<T>>(Containers); }
    template <typename T>
    std::vector<T>& GetContainer() { return std::get<std::vector<T>>(Containers); }

private:
    std::tuple<std::vector<Ts>...> Containers;
};