Шаблонная многошаговая реализация - как? - PullRequest
0 голосов
/ 19 апреля 2020

Мне нужен «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;

};

Теперь я мог бы использовать старый трюк, помещая Контейнер в функцию-член, например

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

но мне больше не нравится это в эпоху многопоточности. Это «опасно», верно!?

Есть ли лучший, элегантный способ? Вполне возможно, что я заранее знаю разрешенные типы, если это поможет их реализовать.

1 Ответ

1 голос
/ 19 апреля 2020

но мне больше не нравится это в эпоху многопоточности. Это «опасно», верно!?

Проблема не в многопоточности. инициализация будет в порядке. Вы все равно должны защищать / синхронизировать доступ, как обычный многопоточный код.

Проблема заключается в том, что контейнер не соответствует экземпляру MultiTask, так как это stati c. Это в основном, как если бы 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;
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...