c ++ STL algo remove_if используется с шаблоном - PullRequest
2 голосов
/ 26 января 2012

Я попытался применить алгоритм stl remove_if к шаблону и столкнулся с некоторыми проблемами.Любая помощь приветствуется!

template <class T> bool flag_delete(pair<T,int> a) {return (a.second == 1);}

template <class T> void fun_delete_by_flag(vector<T> &vec_data, ivec &vec_flag)
{
    int n = vec_data.size();
    vector< pair<T,int> > vec;
    vec.resize(n);
    for ( int i = 0; i < n; i += 1 ) {
        vec[i].first = vec_data[i];
        vec[i].second = vec_flag[i];
    }
    typename vector< pair<T,int> >::iterator it;
    it = remove_if(vec.begin(), vec.end(), flag_delete);
    n = vec.size();
    vec_data.resize(n);
    for ( int i = 0; i < n; i += 1 ) {
        vec_data[i] = vec[i].first;
    }
    return;
}

Я получил следующее сообщение:

guess_algo.h: In function ‘void fun_delete_by_flag(std::vector<T>&, ivec&) [with T = std::pair<int, std::basic_string<char> >, ivec = std::vector<int>]’:
user_time.h:63:34:   instantiated from here
guess_algo.h:61:2: error: no matching function for call to ‘remove_if(std::vector<std::pair<std::pair<int, std::basic_string<char> >, int>, std::allocator<std::pair<std::pair<int, std::basic_string<char> >, int> > >::iterator, std::vector<std::pair<std::pair<int, std::basic_string<char> >, int>, std::allocator<std::pair<std::pair<int, std::basic_string<char> >, int> > >::iterator, <unresolved overloaded function type>)’

Ответы [ 3 ]

3 голосов
/ 26 января 2012

Независимо от того, что высказали другие (необходимо указать конкретный параметр шаблона), вы пропускаете вызов std::vector::erase (или вызов vec_data.resize() является избыточным).

std::remove_if делает не уменьшение размера контейнера!

Итак, либо добавьте отмеченную строку

auto it = remove_if(vec.begin(), vec.end(), flag_delete<T>);
vec.erase(it);        // <-- ADD THIS TO ACTUALLY REDUCE CONTAINER LENGTH
n = vec.size();
vec_data.resize(n);

Или переписать немного. Зная, что векторное распределение является смежным в соответствии со стандартом, вы можете сжать все это до (при условии поддержки c ++ 0x):

template <class T> void simpler(vector<T> &vec_data, const ivec &vec_flag)
{
    T *begin = &vec_data.front();
    size_t newsize = std::distance(begin, 
            std::remove_if(
                begin, begin + vec_data.size(), [&] (T& el) 
                { 
                    return 1 == vec_flag[std::distance(begin, &el)]; 
                }));

    vec_data.resize(newsize);
}

Посмотреть вживую: http://ideone.com/S2WUC

Редактировать Я также немного очистил исходную функцию (примечание const&, size_t, erase, reserve и std::make_pair):

template <class T> void fun_delete_by_flag(vector<T> &vec_data, const ivec &vec_flag)
{
    size_t n = vec_data.size();
    vector< pair<T,int> > vec;
    vec.reserve(n);
    for ( size_t i = 0; i < n; i += 1 ) 
        vec.push_back(std::make_pair(vec_data[i], vec_flag[i]));

    vec.erase(remove_if(vec.begin(), vec.end(), flag_delete<T>));

    n = vec.size();
    vec_data.resize(n);

    for ( size_t i = 0; i < n; i += 1 )
        vec_data[i] = vec[i].first;

    return;
}
3 голосов
/ 26 января 2012

Вам нужно изменить ваш вызов remove_if следующим образом:

it = remove_if(vec.begin(), vec.end(), flag_delete<T>);

т.е.добавьте <T> в конце flag_delete, потому что вы не сказали, что функция должна иметь тот же параметр шаблона, что и для fun_delete_by_flag.Подсказка - это (довольно хорошо спрятанный) <unresolved overloaded function type> в конце сообщения об ошибке.

0 голосов
/ 26 января 2012

Попробуйте взглянуть на первую строку сообщений об ошибках:

guess_algo.h: In function ‘void fun_delete_by_flag(std::vector<T>&, ivec&) [with T = std::pair<int, std::basic_string<char> >, ivec = std::vector<int>]’:

Это говорит о том, что T является типом pair.И последняя строка сообщает вам (в конце), что вы вызываете «неразрешенный тип перегруженной функции».Это означает, что вы задаете ему параметры, отличные от определенных в функции flag_delete.

Из первого сообщения об ошибке вы даете ему пару.Попробуйте проверить свои типы и, возможно, сменить T на другой символ.

...