Сообщения

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

В некоторых случаях компиляторы С++ не могут выбрать подходящую перегружаемую функцию, например, в очевидной с человеческой точки зрения ситуации — возникает ошибка компиляции: 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 не обязана возвр...

Полезные новации С++17. Выражения свертки (Fold expressions)

Начиная с C++11, в языке появились пакеты параметров для шаблонов с переменным количеством аргументов. Такие пакеты позволяют реализовывать функции, принимающие переменное количество параметров. Иногда эти параметры объединяются в одно выражение, чтобы на его основе можно было получить результат работы функции. Решение этой задачи значительно упростилось с выходом C++17, где появились выражения свертки. Реализуем функцию, которая принимает переменное количество параметров арифметических типов и возвращает их сумму. template <typename ... Ts> auto sum(Ts ... ts) {    return (ts + ...); }     Следует обратить внимание на обязательность скобок в выражении  (ts + ...).  Функцию можно использовать так: int the_sum {sum(1, 2, 3, 4, 0.5)}; // Значение: 10.5    Общий смысл понятен. Поработаем над деталями. Первое наше упущение - отсутствие возможности работать с пустым списком параметров. Инстанцирование  sum() приводит к ошибке ...