Как использовать std :: bind () для вызова версии виртуальной функции базового класса?

Я пытаюсь использовать std :: bind () для создания функции, которая будет вызывать версию виртуальной функции базового класса, а не вызывать версию производного класса.

struct Base
{
    virtual void foo() { cout << "Base\n"; }
};

struct Derived : public Base
{
    virtual void foo() { cout << "Derived\n"; }
};

int main(int argc, const char * argv[])
{
    Base* base = new Derived;
    auto baseMethodHopefully = std::bind( &Base::foo, base );
    baseMethodHopefully();    // Want call to Base::foo(), but get call to Derived::foo().

    return 0;
}

Насколько я понимаю из в другом месте, вы обычно не может вызывать базовую функцию "антивиртуальным" способом, подобным этому. Очевидное исключение - это общепринятая парадигма:

void Derived::bar() { Base::bar(); }

Поскольку выражение Base::bar() распознается как "антивиртуальное" (в том смысле, о котором я говорю) в методах Derived, возможно ли выполнить привязку к Base::bar() желаемым способом из внутри одного из методов Derived ? Например. что-то типа:

void Derived::bar()
{
    auto baseMethod = std::bind( &Base::foo, this );
    baseMethod();
}

Если да, то каков синтаксис?


person OldPeculier    schedule 18.01.2013    source источник


Ответы (1)


Ну, &Base::foo - указатель на функцию-член. И нет способа использовать указатель на функцию-член, который не вызывает виртуальное переопределение. Единственный синтаксис, позволяющий избежать виртуальных переопределений, - это тот, в котором имя класса, имя функции и список аргументов находятся в одном выражении.

Но если у вас есть std::bind, у вас, вероятно, также есть лямбды, поэтому, возможно, вы могли бы использовать:

auto baseMethod = [this](){ return Base::foo(); };
//...
baseMethod();
person aschepler    schedule 18.01.2013
comment
Сладкий. Работает как шарм. Спасибо! - person OldPeculier; 19.01.2013
comment
Извините, я не поняла. Как можно члену функционировать без объекта? - person balki; 19.01.2013
comment
Это лямбда-выражение работает только в функции-члене Base или Derived (или другого подкласса Base) и захватывает this. - person aschepler; 19.01.2013
comment
@aschepler, в моем компиляторе (Apple LLVM Compiler 4.1) требуется this, или я получаю сообщение об ошибке: error: 'this' не может быть неявно зафиксировано в этом контексте. Отсюда и мое более раннее редактирование. - person OldPeculier; 22.01.2013
comment
Да, [this] необходим. Отредактировано. - person aschepler; 08.12.2015