【问题标题】:Templated multistack implementation - how?模板化多栈实现 - 如何?
【发布时间】:2020-08-01 15:01:47
【问题描述】:

我需要一个“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;
}

但在多线程时代我不再喜欢这样了。很“危险”吧!?

有没有更好、更优雅的方式?可以想象,我事先知道允许的类型,如果这有助于实现它。

【问题讨论】:

  • @DivyanshSingh 一点也不。我有没有提到我正在寻找一个“优雅”的解决方案?我已经有 3 种特定类型的代码,但我需要添加更多,所以出现了这个问题。
  • 首先GetContainer返回一个副本,所以不会做任何对你有用的事情。但即使它会返回一个引用或指向它的指针,static std::vector&lt;T&gt; C 也会在MultiStack 的不同实例之间共享。
  • 你的意思是'last of all'还是'least of all'?显然,意图是&,但感谢您的指导。

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


【解决方案1】:

但在多线程时代我不再喜欢这个了。很“危险”吧!?

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

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

可以想象,我事先知道允许的类型,如果这有助于实现它。

这有帮助,然后您可以使用 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;
};

【讨论】:

  • 看起来不错。但是,如果使用不受支持的 T 调用会发生什么?
  • 有道理。必须自己处理。
  • 你可以添加类似static_assert((std::is_same_v&lt;T, Ts&gt; || ...))
  • 元音节。漂亮的std::get&lt;T&gt; 拯救了一天。
猜你喜欢
  • 1970-01-01
  • 2016-08-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多