LINUX.ORG.RU

[C++][Ступор] Манипуляции с функциями

 


0

3

Пусть есть функция от N переменных:
double func(double x1, double x2, ..., double xN);
Возник вопрос, как бы ее преобразовать в функцию с одним (или N-1) переменным
Есть ли у кого какие нибудь идеи? Как вообще правильно хранить функции в программе (например при решении нелинейных систем)? *fixed

★★

Последнее исправление: sol_linux (всего исправлений: 1)

man STL

Точнее, адаптеры. adaptor2nd это называется, кажется, щас не помню навскидку. Ну, и хранить, соответственно, в виде «функторов» (классов-функций).

alegz ★★★★
()

Это называется карринг, и как правильно тебе сказали, можно взять std::bind1st, std::bind2nd. А еще можно посмотреть на boost:bind

unanimous ★★★★★
()
#include <iostream>

double func(double x, double y) {
    return x * y;
}

int main() {
    auto newFunc = [](double n) {
        return func(n, 0.5);
    };

    std::cout << newFunc(10) << std::endl;
}
anonymous
()
Ответ на: комментарий от unanimous

Да, хотя в gcc до сих опция -std=c++0x.

anonymous
()
Ответ на: комментарий от sol_linux

В том примере лямбды из С++11, еще стоит упомямуть о std::function.

Begemoth ★★★★★
()
Ответ на: man STL от alegz

Я кажется не очень точно написал топик. Функция n переменных и надо получить из нее функцию от одной переменной. Почитал тут bind1st и bind2nd возращают унарный функтор.

sol_linux ★★
() автор топика
Ответ на: комментарий от sol_linux

Ну да, они у тебя все равно одного типа.

anonymous
()

Ладно, а есть ли какие нибудь идеи как функции можно конструировать. Вот например: на входе строка «sin(cos(ln(x)))» и необходимо вернуть функтор, вычисляющий это выражение

sol_linux ★★
() автор топика
Ответ на: комментарий от sol_linux
#include <cmath>
#include <iostream>

template<typename...> class combiner;

template<typename F>
struct combiner<F>: F {
    combiner(const F &f): F(f) {}
};

template<typename F1, typename... F>
class combiner<F1, F...>: public combiner<F...> {
    F1 f1;
public:
    typedef typename F1::result_type result_type;
    combiner(F1 f1, F... f): f1(f1), combiner<F...>(f...) {}
    template<typename... Args>
    result_type operator ()(Args&&... args) {
        return f1(combiner<F...>::operator ()(std::forward<Args>(args)...));
    }
};

template<typename... F>
combiner<F...> combine(F... f) {
    return combiner<F...>(f...);
}

int main() {
    using namespace std;
    auto f = combine(ptr_fun((double (*)(double))sin),
        ptr_fun((double (*)(double))cos),
        ptr_fun((double (*)(double))log));
    cout << f(1) << endl;
}
const86 ★★★★★
()
Ответ на: комментарий от const86

Это круто, но я мало что понял. Видимо надо параллельно почитывать маны по C++11, хотя я даже пока в STL не мастер.

sol_linux ★★
() автор топика
Ответ на: комментарий от const86

Можно эту лямбду куда-нибудь передать в качестве аргумента? Положить в вектор? Вернуть из другой функции?

anonymous
()
Ответ на: комментарий от anonymous

> Можно эту лямбду куда-нибудь передать в качестве аргумента? Положить в вектор? Вернуть из другой функции?

Нельзя угадать тип лямбды и у разных лямбд он разный (в вектор трудно запихивать). Но его можно выводить через auto, параметры шаблона (для передачи в функцию как аргумент) или через decltype (для возврата из функции, но буков много выйдет). Можно завернуть в std::function, тогда на все три вопроса ответ положительный, только function динамически выделяет память под своё нутро.

const86 ★★★★★
()
Ответ на: комментарий от unixware

> Это уже давно есть на D :)

А в хаскеле это от рождения и букв меньше писать. Что ж. В плюсах тоже вот есть.

const86 ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.