Сообщения

25 лет книге Александреску

Книга Андрея Александреску «Modern C++ Design» (2001) оказала глубокое влияние на развитие C++, но ее влияние на стандарты проявлялось не в прямом заимствовании готового кода, а через демонстрацию новых возможностей шаблонов и формирование запроса сообщества на языковые средства, которые сделали бы эти техники более удобными и безопасными . Сам термин «современный C++» (modern C++) сегодня часто ассоциируется именно со стилем, который популяризировала эта книга . Вот основные направления влияния. Формирование «Современного C++» как парадигмы Книга показала, что шаблоны C++ — это не просто механизм для контейнеров (как в STL), а полноценный язык метапрограммирования, позволяющий генерировать высокоэффективный и гибкий код на этапе компиляции . Идея policy-based design (проектирование на основе стратегий), представленная в книге, стала основой для создания компонентов, которые легко адаптируются к контексту использования . Конкретные технические концепции, повлиявшие на стандарт Хо...

Помощь компилятору С++ в разрешении перегрузки функций

В некоторых случаях компиляторы С++ не могут выбрать подходящую перегружаемую функцию, например, в очевидной с человеческой точки зрения ситуации — возникает ошибка компиляции: void f(int i){} void f(string s){} vector<int> int_c = { 1, 2, 3, 4, 5 }; vector<string> string_c = { "Sic" ,"transit" ,"gloria" ,"mundi" }; for_each(begin(int_c), end(int_c), f);//error C2672: "for_each": не найдена соответствующая перегруженная функция Проблема – в отсутствии параметров у f в последней строке, по которым компилятор мог бы произвести разрешение перегрузки. То, что параметрами for_each передаются итераторы вполне определенного типа – для компилятора не имеет значения. Можно предложить несколько «лобовых» способов решения проблемы: 1) Использование static_cast<>() для принудительного приведения к указателю на функцию нужного типа. Приводим к указателю на void f(int i): std::for_each(begin(int_c), end(int_c), static_cast<v...

for_each_arg: Вызов функции для каждого аргумента функции

Вольный перевод статьи  . Как вызвать функцию для каждого аргумента другой функции? Например, у нас есть функция template < typename . . . Args > void g ( Args && . . . args ) {    // ... } и мы хотим применить некую функцию f к каждому аргументу функции g. Требуется некий for_each_arg, который позволит выполнить следующее: template < typename . . . Args > void g ( Args && . . . args ) {    for_each_arg ( f , args . . . ) ; } Как это решить с компилятором, не поддерживающим C++17? Используем  std :: initializer_list, в список аргументов которого будем передавать результаты вызовов f c аргументами args: std :: initializer_list < ? > { ( f ( args ) ) . . . } Возникают проблемы: 1) Не знаем rvalue или lvalue передается в args - используем std::forward. 2) Какого типа элементы содержит  std :: initializer_list < ? >  . Допустим, что int, но функция f не обязана возвр...