Прочитав о Назначенных адресуемых функциях, я понял, что получение адреса стандартной библиотечной функции — это поведение undefined.
Теперь я не знаю, как переписать свой код, который всегда берет адрес стандартных функций.
#include <iostream>
#include<vector>
#include<cmath>
bool divisible_3(double n){
return int(n)%3==0;
}
void applyFunction(std::vector<double>& vector, bool(* filterf)(double), double(*calc)(double)){
for(int index=0;index<int(vector.size());index++){
if (filterf(vector[index])){
vector[index]=calc(vector[index]);
}
}
}
int main(){
std::vector<double> vect = {1, 2, 3, 5, 9, 16, 21, 24};
applyFunction(vect,divisible_3,std::sqrt);
for(auto&& i: vect){
std::cout << i << std::endl;
}
}
вы всегда можете создать свою собственную функцию, которая просто вызывает sqrt
Самый простой способ — написать функцию, которую вы можете вызывать, которая вызывает sqrt()
. Кстати, в терминологии используется «адрес», а не «направление».
Есть несколько вариантов. Первый самый очевидный: напишите собственную функцию делегирования. std::sqrt
может быть неадресуемой функцией, но знаете, что адресно?
double totally_not_std_sqrt(double input) {
return std::sqrt(input);
}
Эта функция является полностью адресуемой, поэтому ее можно передать в качестве аргумента в полностью стандартном C++.
Другой, более компактный вариант — использовать лямбду.
applyFunction(vect, divisible_3, [](double x) { return std::sqrt(x); });
Теперь вы можете подумать: «лямбды можно преобразовать в std::function
, но я беру указатель на функцию». Это правда. Но лямбда-выражения, которые не захватывают, можно преобразовать в указатели на функции, поэтому даже если ваша функция принимает указатель на функцию, она все равно может принимать лямбда-выражения без захвата. (Вы можете подумать о том, чтобы ваша функция взяла std::function
, если только вы не планируете взаимодействовать с C, но это еще одна проблема)
Согласно размещенной вами ссылке, не указано (не определено) использование адреса стандартной библиотечной функции.