Рассмотрим следующий код.
std::vector do_processing()
{
pqxx::result input_data = get_data_from_database();
return process_data(input_data);
}
std::vector process_data(pqxx::result const & input_data)
{
std::vector ret;
pqxx::result::const_iterator row;
for (row = input_data.begin(); row != inpupt_data.end(); ++row)
{
// somehow populate output vector
}
return ret;
}
Пока я думал о том, могу ли я ожидать оптимизации возвращаемого значения (RVO ), я нашел этот ответ Джерри Коффина [курсив мой]:
At least IMO, it's usually a poor idea, but not for efficiency reasons. It's a poor idea because the function in question should usually be written as a generic algorithm that produces its output via an iterator. Almost any code that accepts or returns a container instead of operating on iterators should be considered suspect.
Don't get me wrong: there are times it makes sense to pass around collection-like objects (e.g., strings) but for the example cited, I'd consider passing or returning the vector a poor idea.
Имея некоторый опыт работы с Python, мне очень нравятся генераторы. На самом деле, если бы это был Python, я бы написал выше функцию как Генератор, т.е. чтобы избежать необходимости обработки всех данных до того, как что-то еще может произойти. Например вот так:
def process_data(input_data):
for item in input_data:
# somehow process items
yield result_data
Если я правильно истолковал записку Джерри Коффина, это то, что он предложил, не так ли? Если да, то как я могу реализовать это на С++?