#c 11 #boost #boost-adaptors
#c 11 #повышение #boost-адаптеры
Вопрос:
Пожалуйста, рассмотрите этот некомпилируемый код:
#include <boost/range/adaptors.hpp>
class Stuff {
public:
bool var;
};
class Manager {
/// Get everything
std::vector<Stuff*>
get_all_stuff() const
{
return list_of_stuff;
}
/// Get a vector of only those that whose "var" matches the "tf" argument.
std::vector<Stuff*>
get_some_stuff(const bool tf) const
{
return (get_all_stuff() |
boost::adaptors::filtered(
[](Stuff constamp; s) { return (s.var == tf); }
)
);
}
private:
std::vector<Stuff*> list_of_stuff;
};
Компиляция завершается с этой ошибкой:
ex.cc: In lambda function:
ex.cc:21:46: error: ‘tf’ is not captured
[](Stuff constamp; s) { return (s.var == tf); }
^
1.) Как мне перенести этот аргумент функции в мой lambda?
2.) Является ли это опасным подходом? Должен ли я использовать std::remove_copy_if() вместо этого?
- Я НЕ беспокоюсь о времени жизни вектора, возвращаемого «get_all_stuff()».
- Меня беспокоит время жизни вектора, возвращаемого «get_some_stuff()».
Ответ №1:
Чтобы получить внешнее значение в лямбде, вы должны его зафиксировать.
[amp;tf](Stuff constamp; s) { return (s.var == tf);
Я использовал boost::adaptors::filter
в примере. Но ether one вернет диапазон, а не векторный объект. Если вы хотите вернуть вектор, который отличается от list_of_stuff
, вам придется его построить. Если вы вернете его из своей функции, компилятор переместит его, если это возможно. Вот рабочий пример на coliru.
#include <iostream>
#include <boost/range/algorithm.hpp>
#include <boost/range/adaptors.hpp>
class Stuff {
public:
bool var;
int id;
};
std::ostreamamp; operator << (std::ostreamamp; os, const Stuff stuff) {
return os << std::boolalpha << stuff.id << " " << stuff.var;
}
using vector_type = std::vector<Stuff>;
class Manager {
/// Get everything
public:
auto get_all_stuff() const
{
return list_of_stuff;
}
// Get a vector of only those that whose "var" matches the "tf" argument.
vector_type get_some_stuff(const bool tf) const
{
vector_type temp;
for (auto item : boost::adaptors::filter(list_of_stuff,
[amp;tf](Stuff constamp; s) { return s.var == tf; }))
temp.push_back(item);
return temp;
}
private:
vector_type list_of_stuff = { {false,1},{true,2},{false,3},{true,4},{true,5} };
};
int main()
{
Manager manage;
for (const auto item : manage.get_all_stuff())
std::cout << item << " ";
std::cout << std::endl;
for (const auto item : manage.get_some_stuff(true))
std::cout << item << " ";
std::cout << std::endl;
}
Комментарии:
1. Спасибо @lakeweb! Требуется ли вашему коду C 17, как в примере с Coliru? Мне нужен C 11…
2. Доброе утро. Итак, я перешел к gcc.godbolt.org поскольку я не мог получить никаких ошибок с MS, установленным по умолчанию (который, я думаю, является c 11). Единственное, о чем он отказался, был тип автоматического возврата
get_all_stuff()
. Изменил его наvector_type
и он скомпилировался.3. Спасибо @lakeweb!