синтаксис шаблона для контейнеров - PullRequest
1 голос
/ 12 апреля 2011

Вот что у меня сейчас:

template<template<typename T> class container, typename T>
inline bool contains( const container<T> &cont, const T &element )
{
    if( cont.size() == 0 )
        return false;

    return( std::find(cont.begin(), cont.end(), element) != cont.end() );
}

А я бы хотел назвать это так:

std::vector<string> stringvector;
contains( stringvector, "somestring" );

Я считаю, что это возможно, но все, что я пробовал, выдает другую ошибку. Любая помощь приветствуется. Спасибо!

ОБНОВЛЕНИЕ: Спасибо за все ответы уже, я смотрел слишком далеко, но у меня все еще есть проблемы:

template<class container_type, typename T>
inline bool contains(const container_type& c, const T& e)
{
    return !(c.size() && std::find(c.begin(),c.end(),e)!=c.end());
}

int main(int argc, char *argv[])
{
    vector<string> stringvector;
    stringvector.push_back("hello");
    cout << contains( stringvector, string("hello") );
    return 0;
}

не компилируется, даже без явного конструктора `string ':

error: no matching function for call to 'find(std::vector<std::basic_string<char> >::const_iterator, std::vector<std::basic_string<char> >::const_iterator, const std::basic_string<char>&)'

Ответы [ 4 ]

5 голосов
/ 12 апреля 2011

STL-контейнеры принимают два аргумента, один для содержимого типа и другой для распределителя, описывающего, как получить память.

Попробуйте это:

template<template<typename T, typename Alloc> class container, typename T, typename Alloc>
inline bool contains( const container<T, Alloc > &cont, const T &element )

Однако это действительно хороший пример того, почему вам вообще следует избегать алгоритмов параметризации для контейнеров. Лучше всего следовать шаблону <algorithm> и указывать только параметры типа итератора.

template< typename Iter, typename T >
inline bool contains( Iter first, Iter last, const T &element )
    { return std::find( first, last, element ) != last; }

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

template< typename Cont, typename T >
inline bool contains( Cont const &cont, T const &element )
    { return std::find( cont.begin(), cont.end(), element ) != cont.end(); }
3 голосов
/ 12 апреля 2011

Почему не просто

template<class container_type,typename T>
inline bool contains(const container_type& c,const T& e) {
    return !(c.size() && std::find(c.begin(),c.end(),e)!=c.end());
}
2 голосов
/ 12 апреля 2011

Попробуйте:

template <class T> 
bool contains(const T & cont, const typename T::value_type & elem)
{
   return( std::find(cont.begin(), cont.end(), elem) != cont.end() );
}

Большинство стандартных контейнеров имеют value_type typedef, который упрощает это.

0 голосов
/ 12 апреля 2011

Это проще, чем просто ... просто рассмотрите контейнер и тип элемента как параметры шаблона ...

#include <vector>
#include <list>
#include <set>
#include <string>
#include <algorithm>
#include <iostream>

template<typename C, typename E>
bool contains(const C& c, const E& e)
{
    return std::find(c.begin(), c.end(), e) != c.end();
}

int main()
{
    std::vector<std::string> V;
    std::list<std::string> L;
    std::set<std::string> S;

    V.push_back("Foo"); L.push_back("Foo"); S.insert("Foo");
    V.push_back("Bar"); L.push_back("Bar"); S.insert("Bar");

    std::cout << contains(V, "Foo") << std::endl;
    std::cout << contains(L, "Foo") << std::endl;
    std::cout << contains(S, "Foo") << std::endl;

    std::cout << contains(V, "Baz") << std::endl;
    std::cout << contains(L, "Baz") << std::endl;
    std::cout << contains(S, "Baz") << std::endl;

    return 0;
}

Обратите внимание, что, например, в приведенном выше коде я использую contains также с std::set, где std::find не является умным способом поиска вещей (std::set::find может работать лучше, чем O (n)) .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...