В процессе подготовки доклада к GECon-2017 столкнулся с необходимостью привести небольшой, но яркий пример отличия кода на C++11/14 от кода на C++98. Пока в качестве примера я хочу привести код, который наполняет std::vector несколькими значениями, копирует оттуда те элементы, которые удовлетворяют некоторому условию в другой вектор, затем результирующий вектор сортируется и отображается через std::cout. В коде на С++98 это будет сделано через функторы и итераторы. В коде на C++11/14 это уже будет с initializer lists, лямбдами, туплами и range-for.
Однако, есть подозрение, что данный пример окажется слишком объемным и невыразительным. А это не есть хорошо.
К сожалению, с хорошими примерами происходит как с анекдотами: когда очень нужно, то хрен вспомнишь. А когда вспоминаешь, то вокруг уже никого нет.
Посему обращаюсь к читателям: есть ли у вас самые яркие впечатления от знакомства с C++11/14? Вот увидели какой-то код на C++11/14 и поняли, что C++ стал другим и то, что в С++98 требовало кучи приседаний, в C++11/14 записывается легко и непринужденно. Если есть, то не сочтите за труд, поделитесь, пожалуйста.
Upd. Под катом варианты, которые есть на данный момент.
Код для C++98/03:
#include <algorithm> #include <iostream> #include <string> #include <vector> using namespace std; struct place { string name_; float price_; int rating_; place() {} place(const char * name, float price, int rating) : name_(name), price_(price), rating_(rating) {} }; bool compare_by_rating_and_name(const place & a, const place & b) { return a.rating_ < b.rating_ || (a.rating_ == b.rating_ && a.name_ < b.name_); } struct price_less_than { const float price_; price_less_than(float price) : price_(price) {} bool operator()(const place & p) { return p.price_ < price_; } }; template<class In_It, class Out_It, class P> Out_It copy_n_if(size_t n, In_It b, In_It e, Out_It to, P predicate) { for(; n && b != e; ++b) if(predicate(*b)) { *to = *b; ++to; --n; } return to; } vector<place> fill_places() { vector<place> places; places.push_back(place("Moscow", 1500, 3)); places.push_back(place("St. Petersburg", 1300, 5)); places.push_back(place("Minsk", 500, 4)); places.push_back(place("Tokyo", 3500, 4)); places.push_back(place("Sydney", 5000, 3)); places.push_back(place("Paris", 3000, 5)); return places; } int main() { const vector<place> places = fill_places(); place result[10]; place * result_end = copy_n_if( sizeof(result)/sizeof(result[0]), places.begin(), places.end(), result, price_less_than(4000)); sort(result, result_end, compare_by_rating_and_name); for(place * i = result; i != result_end; ++i) cout << i->name_ << " (" << i->rating_ << ", " << i->price_ << ")" << endl; } |
Проверялся под MinGW GCC 7.1 с ключами -std=c++03, -pedantic, -Wall.
Код для C++14:
#include <algorithm> #include <array> #include <iostream> #include <string> #include <vector> #include <tuple> using namespace std; struct place { string name_; float price_; int rating_; }; bool compare_by_rating_and_name(const place & a, const place & b) { const auto t = [](const auto & p) { return tie(p.rating_, p.name_); }; return t(a) < t(b); } template<class Source, class Out_It, class P> Out_It copy_n_if(size_t n, const Source & src, Out_It to, P predicate) { for(auto b = begin(src), e = end(src); n && b != e; ++b) if(predicate(*b)) { *to = *b; ++to; --n; } return to; } vector<place> fill_places() { return {{"Moscow", 1500, 3}, {"St. Petersburg", 1300, 5}, {"Minsk", 500, 4}, {"Tokyo", 3500, 4}, {"Sydney", 5000, 3}, {"Paris", 3000, 5}}; } int main() { const auto places = fill_places(); array<place, 10> result; auto result_end = copy_n_if( result.size(), places, begin(result), [](const auto & p){ return p.price_ < 4000; }); sort(begin(result), result_end, compare_by_rating_and_name); for(auto i = begin(result); i != result_end; ++i) cout << i->name_ << " (" << i->rating_ << ", " << i->price_ << ")" << endl; } |
Проверялся под MinGW GCC 7.1 с ключами -std=c++14, -pedantic, -Wall.
Комментариев нет:
Отправить комментарий