Создать список функций

116
12 августа 2019, 01:00
  1. Помогите сделать список ф-ций.
  2. Значения по умолчанию будут ли работать?

И если есть советы как запомнить, буду благодарен)

class A {
public:
    A();
    void f0(bool b = true);
    void f1(bool b = true);
    void f2(bool b = true);
    std::list<???> listFunc;    // тут нужна помощь
    //QList<???> listFunc;
}
A::A() {
    listFunc.append(f0);
    listFunc.append(f1);
    listFunc.append(f2);
}
void main() {
    A a;
    a.listFunc.at(1)(false);// или a.listFunc[1](false);
    a.listFunc.at(0)();
}
Answer 1

Ваши "функции" - это не просто функции, а методы класса. Из вашего вопроса не ясно, для какого объекта вы собираетесь вызывать эти методы класса.

Например

std::list<std::function<void(bool)>> listFunc;

и далее

listFunc.push_back(std::bind(&A::f0, this, std::placeholders::_1));
listFunc.push_back(std::bind(&A::f1, this, std::placeholders::_1));
listFunc.push_back(std::bind(&A::f2, this, std::placeholders::_1));

или через лямбды

listFunc.push_back([this](bool b) { f0(b); });
listFunc.push_back([this](bool b) { f1(b); });
listFunc.push_back([this](bool b) { f2(b); });

Вызов

listFunc.front()(false);

В таком варианте привязка конкретного объекта (this) делается в момент заполнения списка.

Можно поступить и по старинке

std::list<void (A::*)(bool)> listFunc;

далее

listFunc.push_back(&A::f0);
listFunc.push_back(&A::f1);
listFunc.push_back(&A::f2);

Но вызов тогда будет таким

(a.*listFunc.front())(false);

В таком варианте указание конкретного объекта (a) делается в момент вызова.

Применение std::function в первом варианте привносит лишние накладные расходы, во многих случаях совершенно не оправданные. Но из-за того, что ни тип std::bind, ни тип лямбды в С++ не является однозначно определенным, приходится таки волей-неволей использовать std::function. (В этом отношении устаревший std::bind1st был лучше.)

Более эффективной альтернативой первому варианту может быть "ручная" реализация

struct Af
{
  A *self;
  void (A::*f)(bool);
  void operator ()(bool b) const
    { (self->*f)(b); }
};

и далее

std::list<Af> listFunc;
...
listFunc.push_back({ this, &A::f0 });
listFunc.push_back({ this, &A::f1 });

и вызов

listFunc.front()(false);
Answer 2
class A {
public:
    A();
    void f0(bool b = true);
    void f1(bool b = true);
    void f2(bool b = true);
    std::list<void (A::*)(bool)> listFunc;    // ??? ????? ??????
    //QList<???> listFunc;
};
A::A() {
    listFunc.push_back(&A::f0);
    listFunc.push_back(&A::f1);
    listFunc.push_back(&A::f2);
}
int main() {
    A a;
    for(auto f: a.listFunc)
        (a.*f)(false);// ??? a.listFunc[1](false);
}

Естественно, что значения по умолчанию работать не будут, потому что их подстановка выполняется во время компиляции; у вас же функции вызываются по адресу, и какая именно функция будет вызвана - компилятор определить не в состоянии.

READ ALSO
Объект класса в качестве значения map

Объект класса в качестве значения map

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

125
Ошибка компиляции на месте вызова printf()

Ошибка компиляции на месте вызова printf()

Почему вот это работает,

117
Как расширять структуру / класс вне его / ее объявления?

Как расширять структуру / класс вне его / ее объявления?

Никак не могу понять как на примере интерпретатора python можно расширять главный PyObject дополняя его методами и другими объектами не правя саму...

93
Библиотека libxl не видит файл

Библиотека libxl не видит файл

Пытаюсь проверить работоспособность примера библиотеки libxl:

106