Можете ли вы передать дополнительный параметр предикату?

Я пытаюсь отфильтровать вектор, чтобы он содержал только определенное значение.

например Убедитесь, что вектор содержит только элементы со значением «abc».

Прямо сейчас я пытаюсь достичь этого с remove_copy_if,

Есть ли способ передать дополнительный параметр предикату при использовании одного из алгоритмов std?

std::vector<std::string> first, second;
first.push_back("abc");
first.push_back("abc");
first.push_back("def");
first.push_back("abd");
first.push_back("cde");
first.push_back("def");

std::remove_copy_if(first.begin(), first.end(), second.begin(), is_invalid);

Я надеюсь передать следующую функцию в качестве предиката, но кажется более вероятным, что это просто закончится сравнением текущего значения, проверяемого remove_copy_if и следующий.

bool is_invalid(const std::string &str, const std::string &wanted)
{
return str.compare(wanted) != 0;
}

У меня есть ощущение, что я, вероятно, подхожу к этому неправильно, поэтому любые предложения будут оценены!

Спасибо

13

Решение

Вместо этого определите функтор:

struct is_invalid
{
is_invalid(const std::string& a_wanted) : wanted(a_wanted) {}
std::string wanted;
bool operator()(const std::string& str)
{
return str.compare(wanted) != 0;
}
};

std::remove_copy_if(first.begin(),
first.end(),
second.begin(),
is_invalid("abc"));

или если C ++ 11 использует лямбду:

std::string wanted("abc");
std::remove_copy_if(first.begin(), first.end(), second.begin(),
[&wanted](const std::string& str)
{
return str.compare(wanted) != 0;
});

Обратите внимание, что выходной вектор, second, должен есть элементы перед вызовом remove_copy_if():

// Create 'second' after population of 'first'.
//
std::vector<std::string> second(first.size());

std::string wanted = "abc";
int copied_items    = 0;
std::remove_copy_if( first.begin(), first.end(), second.begin(),
[&wanted, &copied_items](const std::string& str) -> bool
{
if (str.compare(wanted) != 0) return true;
copied_items++;
return false;
});
second.resize(copied_items);

Так как предикаты функторов копируются, требуется больше усилий для сохранения copied_items Информация. Увидеть Передача предикатов std algos по ссылке в C ++ для предлагаемых решений.

18

Другие решения

Сделать функтор или использовать std/boost::bind,

struct is_invalid
{
public:
is_invalid(const std::string& w):wanted(w) { }
bool operator () (const std::string& str)
{
return str.compare(wanted) != 0;
}
private:
std::string wanted;
};

std::remove_copy_if(first.begin(), first.end(), second.begin(), is_invalid("abc"));

Пример с привязкой

bool is_invalid(const std::string &str, const std::string &wanted)
{
return str.compare(wanted) != 0;
}

std::remove_copy_if(first.begin(), first.end(), second.begin(),
boost::bind(is_invalid, _1, "abc"));
8

По вопросам рекламы [email protected]