2017-05-11 2 views
2

Voici ce que je cherche à atteindre:C++; pointeur de méthode de classe; lambda; passer lambda en tant que pointeur de fonction membre;

class MyClass 
{ 
public: 
    using Callback = void(MyClass::*)(uint8_t idx); 
    void forEach(Callback callback); 

private: 
    int  m_buf[64]; 

    int  m_x; 
    int  m_y; 
    MyObject m_object; 
} 

void MyClass::forEach(Callback callback) 
{ 
    size_t s = m_object.size(); 
    for(size_t i = 0; i < s; i++) 
     callback(i); 
} 

void MyClass::f1() 
{ 
    forEach([this](uint8_t idx) 
    { 
     m_buf[idx]++; 
    }); 
} 

void MyClass::f2() 
{ 
    forEach([this](uint8_t idx) 
    { 
     m_buf[idx] = m_x + m_y * idx; 
    }); 
} 

Donc, il y a un tas de façons de modifier m_buf[]. Afin d'éviter de copier et coller "get size + for loop", je veux ajouter une méthode forEach et passer lambdas comme callbacks. this est capturé pour avoir accès aux membres du cours.

Quelle est la bonne façon d'obtenir le même résultat?
Merci.

PS: compilation de cet exemple renvoie l'erreur 'ne peut pas convertir :: lambda ....'

RÉPONSE: Avec "Passer By" réponse, je finis avec le code:

// Class declaration in header 
using Callback = std::function<void(uint8_t)>; 
void forEach(Callback callback); 

// forEach() is as above 
// forEach() call looks like 
forEach([this](uint8_t idx) { 
    m_buf[idx] = m_x + m_y * idx; 
}); 

J'ai également trouvé quelques questions connexes-réponses qui pourraient être utiles

Passing lambda as function pointer - "5gon12eder" réponse.
C++ lambda with captures as a function pointer

+2

Veuillez faire en sorte que le titre de votre question décrive la question, et pas seulement la liste des choses –

+2

En outre, cette question n'est pas claire. Est-ce que le code que vous avez posté ne fonctionne pas? Sinon, de quelle manière? Et qu'est-ce que tu voulais faire à la place? (nous ne pouvons pas déduire cela du code qui _n'a pas fait ça_) –

+2

Veuillez inclure les messages d'erreur * réels *. Ils ne sont pas du charabia au hasard, mais des informations utiles, et les tronquer n'aide pas. – Quentin

Répondre

2

Vous avez confondu la sémantique d'un pointeur de fonction membre

void (MyClass::*)(uint8_t idx) 

est un pointeur vers une fonction membre de MyClass qui accepte un uint8_t, il n'y a rien d'autre. Vous appelez comme

MyClass::Callback c = &MyClass::SomeMemberFunction; 
MyClass mc; 
(mc.*c)(0); // equivalent to... 
mc.SomeMemberFunction(0); 

En second lieu, le but de for_each est de sorte que l'objet appelable passé dans pas besoin de connaître le fonctionnement interne de l'objet, en tant que tel, vous ne devriez pas passer dans un index dans la boucle.

Ce que vous voulez réellement, c'est transmettre un objet appelable acceptant une référence appelée sur chaque objet. Cela peut se faire de deux façons

template<typename Callable> 
void for_each1(Callable&& call) 
{ 
    for(size_t i = 0; i < size(); i++) 
     call(m_buf[i]); 
} 

#include<functional> 

void for_each2(std::function<void (int&)>&& fn) 
{ 
    for(size_t i = 0; i < size(); i++) 
     fn(m_buf[i]); 
} 

deux peuvent être appelés avec un lambda

MyClass mc; 
mc.for_each1([](int& i) { i++; }); 
mc.for_each2([&mc](int& i) { i += mc.increment(); }); 

mc.increment est ce que veut par exemple être incrémentée.

+0

@Quentin Va montrer que je n'utilise pas vraiment de pointeurs sur la fonction membre, mon (très) mauvais. Merci. –

+0

Pas de soucis :) - – Quentin

+0

@PasserBy, merci. Tu as exactement ce que je voulais :) – user3124812