Конструкторы с функциями в качестве аргументов в переполнении стека

Я получил несколько объектов, переменные которых зависят от разных функций. Другими словами: существует несколько типов функций, на которые опираются переменные в объекте, но должно быть несколько объектов с одинаковыми этими функциями. Для большей очистки я попытался привести пример (который не работает).

#include <iostream>

class A
{
double size;

A( double (*f)() )
{
size = (*f)();
};
};

double fun1()
{
return 42.0;
}int main()
{
A a = A( &fun1() );

std::cout << a.size << std::endl;
}

Это конечно минимальный пример. Размер переменной зависит от определенной функции, которая должна быть передана в качестве аргумента классу. Представить fun1 а также fun2 как разные виды генераторов случайных чисел.

Я думаю, что идеологическим способом в C ++ был бы класс, который содержит переменную, и унаследованные от нее классы модифицируются той функцией, которая отличается от объектов (пожалуйста, исправьте меня, если я ошибаюсь в этом предположении). Но мой вопрос:

Есть ли возможность реализовать какой-то конструктор высшего порядка? Если так, пример был бы хорош.

с .: Если бы я неправильно использовал некоторые технические термины, я был бы рад исправить их.

0

Решение

Изменить на:

A( double (*f)() )
{
size = f();
};

А также:

A a = A( fun1 );

Когда вы проходили &fun1() который пытался вызвать функцию и затем получить адрес ее результата. Что вы на самом деле хотели, так это сам указатель функции, который хранится в fun1,

5

Другие решения

Этот пример не имеет смысла, потому что вы не сохраняете указатель функции для последующего использования. Вы можете переписать это просто

class A
{
double size;

A(double sz) {
size = sz;
};
};

double fun1()
{
return 42.0;
}int main()
{
A a = A(fun1());
std::cout << a.size << std::endl;
}
1

Вместо этого я предлагаю написать шаблон, чтобы вы могли передать любой указатель на функцию или функциональный объект. Это позволяет компилятору легче выполнять оптимизацию, например, во многих случаях, как встраивание, и является более гибким. Вы также не должны использовать скобки при получении указателя на функцию.

#include <iostream>

class A {
public:
template<typename F>
explicit A(F&& f) : size(f()) {

};

double size;
};

double fun1() {
return 42.0;
}

int main() {
A a(&fun1);
std::cout << a.size << std::endl;
}
1

Похоже, вам нужно передать только саму функцию. Вы почти получили это. Вот правильный синтаксис:

typedef double (*functype)();

void foo(functype f) {
cout << f();
}

double bar() {
return 2.39;
)

foo(bar); // don't call bar here, just pass it as address.

Вы также можете объявить foo следующим образом:

void foo(double (*f)());

Функции не являются объектами первого класса в C ++, поэтому единственный способ создать замыкание с некоторыми переменными (например, если вы хотите перенести функцию или вызвать нестатическую функцию-член) — это функторы (объекты с перегруженным оператором () ). Есть несколько способов получить такой объект:

  1. Определите его самостоятельно, сохраните все необходимые переменные в полях и передайте в качестве аргумента функции.
  2. Используйте лямбда-функции C ++ 11 и std :: function
  3. Используйте boost :: function и boost :: bind.
0