Функция, которая принимает любой контейнер STL - PullRequest
2 голосов
/ 27 мая 2020

Мне нужно реализовать функцию шаблона, которая принимает любой контейнер STL. И в зависимости от того, в каком контейнере выполнять определенные действия.

Пример:

template <class Container, class T>
void func(Container<T> container) {
    if (container == std::map) {
        ...
    } else {
        ... 
    }
}


int main() {
    std::vector<int> v1; 
    func(v1); // ok
    std::vector<double> v2;
    func(v2); // ok
    std::map<int, double> m1;
    func(m1); // ok
    std::list<int> l1;
    func(l1); // ok
}

Ответы [ 2 ]

6 голосов
/ 27 мая 2020

Вы можете применить Constexpr If (начиная с C ++ 17) (с std::is_same) для проверки типа во время компиляции и применить пакет параметров (начиная с C ++ 11), потому что эти контейнеры принимают несколько параметров шаблона. например,

template <template <typename...> class Container, class... T>
void func(const Container<T...>& container) {
    if constexpr (std::is_same_v<Container<T...>, std::map<T...>>) {
        ...
    } else if constexpr (std::is_same_v<Container<T...>, std::vector<T...>>) {
        ...
    } else if constexpr (std::is_same_v<Container<T...>, std::list<T...>>) {
        ...
    } else {
        ...
    }
}

PS: Это зависит от вашего намерения, но изменение параметра на pass-by-reference-to-const, чтобы избежать ненужного копирования, может быть хорошей идеей.

2 голосов
/ 27 мая 2020

Поскольку вы в любом случае делаете одну реализацию для каждого контейнера, вы можете делать перегрузки напрямую. Он будет работать на C ++ 11 и имеет то преимущество, что параметры шаблона легко доступны в каждой перегрузке.

template <class T, size_t N>
void func(const std::array<T,N>& c) {
    std::cout << "array " << c.size() << '\n';
}

template <class T, class Alloc>
void func(const std::vector<T,Alloc>& c) {
    std::cout << "vector " << c.size() << '\n';
}

template <class T, class Alloc>
void func(const std::list<T,Alloc>& c) {
    std::cout << "list " << c.size() << '\n';
}

template <class Key, class T, class Comp, class Alloc>
void func(const std::map<Key,T,Comp,Alloc>& c) {
    std::cout << "map " << c.size() << '\n';
}

template <class CharT, class Traits, class Alloc>
void func(const std::basic_string<CharT,Traits,Alloc>& c) {
    std::cout << "basic_string " << c.size() << '\n';
}

// add more of the containers you aim to support here
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...