Как std::bind(&T::memberFunc, this) всегда может связываться с std::function‹void(void)› независимо от того, что такое T?

Насколько я знаю, указатель функции-члена может быть назначен только указателю на тип функции-члена, и преобразование в любой другой, кроме этого, будет нарушать стандарт, верно?

И при вызове std::bind(&T::memberFunc, this) он должен возвращать зависимый тип, который зависит от T. (в стандартной версии VC++ это шаблон класса с именем _Binder).

Таким образом, возникает вопрос, почему один std::funcion может охватывать все типы _Binder(версия VC++).

class A
{
public:
    void func(){}
};
class B
{
public:
    void func(){}
};

std::function<void(void)> f[2];

A a;
B b;
f[0] = std::bind(&A::func, &a);
f[1] = std::bind(&B::func, &b);

И я не могу представить, какой тип члена std::funcion, в котором хранится функция, будет похож, если я не ошибаюсь с самого начала.

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

Но мой вопрос о том, почему один тип std::function может содержать все типы T.


person Francis    schedule 20.03.2018    source источник
comment
Разве ваши привязки не эквивалентны чему-то вроде void f0() { return a.func(); } и void f1() { return b.func(); }?   -  person Jean-Baptiste Yunès    schedule 20.03.2018
comment
Нет. А return a.func();? Что это?@Jean-BaptisteYunès   -  person Francis    schedule 20.03.2018
comment
@francis, вы видели это объяснение?   -  person Smit Ycyken    schedule 20.03.2018
comment
Возможный дубликат Как std::bind работает с функциями-членами   -  person Smit Ycyken    schedule 20.03.2018
comment
Да, но моего ответа там нет. @SmitYcyken   -  person Francis    schedule 20.03.2018
comment
Вопрос в том, как работает стирание шрифта?   -  person T.C.    schedule 20.03.2018
comment
@francis, да, эквивалентно void f0() { a.func(); }   -  person Jean-Baptiste Yunès    schedule 20.03.2018
comment
Я думаю, что это, вероятно, приложение для удаления текста. Пожалуйста, оставьте мне ответ. @T.C.   -  person Francis    schedule 21.03.2018


Ответы (2)


Короче говоря, происходит то, что std::bind(&A::func, &a) возвращает объект класса, похожий на

class InternalClass
{
    A* a_;  // Will be initialized to &a
public:
    void operator()(void)
    {
        a_->func();
    }
};

[Обратите внимание, что это сильно упрощено]

Вызываемая функция operator() соответствует сигнатуре void(void) функции std::function<void(void)>.

person Some programmer dude    schedule 20.03.2018
comment
Все еще в замешательстве. InternalClass по-прежнему является зависимым типом, не так ли? Можете быть более конкретными? - person Francis; 20.03.2018
comment
@francis Что делает твоя привязка? Идея состоит в том, чтобы привязать вызов функции члена к объекту a (и объекту b), не так ли? Тогда какова подпись вызова участника funcна a? Функция, не принимающая параметров и ничего не возвращающая void f(). - person Jean-Baptiste Yunès; 20.03.2018
comment
Да, это равные вещи. Но f0 и f1 разные вещи. Затем std::function волшебным образом покрывает их обоих. то есть std::function охватывает InternalClass<A> и InternalClass<B>. Вот что я пытаюсь понять. @Jean-BaptisteYunès - person Francis; 21.03.2018
comment
@francis std::function заботит только вызываемая функция и ее подпись. - person Some programmer dude; 21.03.2018
comment
Но у A::func и B::func разные подписи, верно? @Someprogrammerdude - person Francis; 21.03.2018

Я думаю, что реализация, вероятно, будет такой:

template</*...*/>
class std::bind</*...*/>
{
public:
    std::bind(callable_t call, param_t p)
    {
    _func = [call, p]()/* using lambda to capture all data for future calling */
    {
    p->call();
    };

}
operator std::function<void(void)>()
{

    return _func;

}
private:
std::function<void(void)> _func;
};

И ключом является лямбда.

person Francis    schedule 08.05.2019