2016-07-21 3 views
0

У меня есть немного проблем с пониманием вызова std :: bind. В следующем примере:Понимание bind

#include <functional> 
#include <iostream> 
#include <memory> 


class Notifier 
{ 
public: 
    Notifier(std::function<void(Notifier&)> on_notify) 
    :on_notify_(on_notify) 
    { } 

    void notify() 
    { 
     if (on_notify_) 
      on_notify_(*this); 
    } 

    std::function<void(Notifier&)> on_notify_; 

}; 

struct Manager 
{ 
    Manager() 
    { 
     n_ = std::make_unique<Notifier>(std::bind(&Manager::trigger, this)); 
    } 

    void trigger() 
    { 
     std::cout << "notified" << std::endl; 
    } 

    std::unique_ptr<Notifier> n_; 
}; 

int main() 
{ 
    Manager s; 
    s.n_->notify(); 
} 

Я не понимаю, как on_notify_(*this); перезванивает функтор с параметром Notifier&, но функтор, созданный bind не определяет его. Вызывает результат правильно для метода void notify(), но я не понимаю, что именно будет функтором, созданным bind, чтобы привести к этому.

Если бы я должен был написать лямбда вместо этого, мне нужно будет указать параметр, иначе он будет компилироваться. Какая операция делает bind здесь за моей спиной? :-)

+0

Существует ссылка на свойства возвращаемого типа [здесь] (http://en.cppreference.com/w/cpp/utility/functional/bind). В частности, его 'operator()'. – chris

+0

Вы могли бы немного подробнее? все еще кажется немного неясным –

+2

@dau_sama «Если некоторые аргументы, которые предоставляются в вызове g(), не сопоставляются с любыми заполнителями, хранящимися в g, неиспользуемые аргументы оцениваются и отбрасываются». – immibis

ответ

2

std::bind в основном игнорирует недействительный данный аргумент согласно this.

Если некоторые аргументы, предоставленные в вызове g(), не совпадают с любыми заполнителями, хранящимися в g, неиспользуемые аргументы оцениваются и отбрасываются.

Это может вас удивить, что при условии еще более абсурдные аргументы, то переплетены функтор еще может успешно достичь Manager::trigger() следующим образом:

#include <functional> 
#include <iostream> 
#include <memory> 

// Some classes that have nothing to do with on_notify_ 
class AAA {}; 
class BBB {}; 

class Notifier 
{ 
public: 
    Notifier(std::function<void(AAA&, BBB&)> on_notify) 
     :on_notify_(on_notify) 
    { } 

    void notify() 
    { 
     if (on_notify_) 
     { 
      // Arguments not matching. 
      AAA a{}; 
      BBB b{}; 

      // Invoke with them. 
      on_notify_(a, b); 
     } 
    } 

    std::function<void(AAA&, BBB&)> on_notify_; 
}; 

struct Manager 
{ 
    Manager() 
    { 
     n_ = std::make_unique<Notifier>(std::bind(&Manager::trigger, this)); 
    } 

    void trigger() 
    { 
     std::cout << "it's also notified!" << std::endl; 
    } 

    std::unique_ptr<Notifier> n_; 
}; 

int main() 
{ 
    Manager s; 
    s.n_->notify(); 
} 

Живая демо here.

Смежные вопросы