C ++ Подобные функции, использующие разные типы данных - PullRequest
0 голосов
/ 30 января 2019

У меня есть две абсолютно одинаковые функции, за исключением того, что одна из них использует stack для своих операций, а другая использует queue:

void doQueue()
{
    std::queue<int> q;
    ...
    ...
    q.push(someValue);
    ...
    ...
    int tmp = q.front();
    q.pop()
}

void doStack()
{
    std::stack<int> s;
    ...
    ...
    s.push(someValue);
    ...
    ...
    int tmp = s.top();
    s.pop()
}

Я хочу устранить дубликатыкод.Поскольку queue использует функцию front для получения первого значения, а stack использует функцию top, я подумал, что шаблоны могут не работать, так как должны вызываться функции с разными именами.

MyДругая идея состояла в том, чтобы создать интерфейс, который будет в качестве обертки для обеих структур данных, и я могу обойти тот, который мне нужен.: * 10101 *

Но я думаю, что должен быть более простой и лучший способвыполните эту операцию.

1 Ответ

0 голосов
/ 30 января 2019

Вот один из способов - шаблон оболочки с частичной специализацией для базового типа контейнера:

#include <stack>
#include <queue>


template<class Container>
struct generic_sequence_ops;

template<class T, class UnderlyingContainer>
struct generic_sequence_ops<std::stack<T, UnderlyingContainer>>
{
    using container_type = std::stack<T, UnderlyingContainer>;
    using value_type = typename container_type::value_type;

    generic_sequence_ops(container_type& c) : c(c) {}

    void add_one(value_type v)
    {
        c.push(std::move(v));
    }

    void remove_one()
    {
        c.pop();
    }

    value_type& current()
    {
        return c.top();
    }

    container_type& c;
};

template<class T, class UnderlyingContainer>
struct generic_sequence_ops<std::queue<T, UnderlyingContainer>>
{
    using container_type = std::queue<T, UnderlyingContainer>;
    using value_type = typename container_type::value_type;

    generic_sequence_ops(container_type& c) : c(c) {}

    void add_one(value_type v)
    {
        c.push(std::move(v));
    }

    void remove_one()
    {
        c.pop();
    }

    value_type& current()
    {
        return c.back();
    }

    container_type& c;
};

template<class Container>
auto make_generic_sequence_ops(Container& cont)
{
    return generic_sequence_ops<std::decay_t<Container>>(cont);
}

template<class Container>
int doContainer(Container& cont)
{
    auto s = make_generic_sequence_ops(cont);

    s.add_one(6);
    int val = s.current();
    s.remove_one();
    return val;
}

int main()
{
    std::queue<int> q;
    std::stack<int> s;

    doContainer(q);
    doContainer(s);
}
...