2008-11-16 4 views
4

J'ai classe avec une fonction membre qui prend un argument par défaut.tr1 :: mem_fn et les membres avec les arguments par défaut

struct Class 
{ 
    void member(int n = 0) 
    {} 
}; 

Au moyen de std :: tr1 :: mem_fn Je peux l'appeler:

Class object; 

std::tr1::mem_fn(&Class::member)(object,10); 

Cela dit, si je veux invoquer le appelable membre de l'objet avec l'argument par défaut, Quelle est la syntaxe correcte?

std::tr1::mem_fn(&Class::member)(object); // This does not work 

g ++ se plaint avec l'erreur suivante:

test.cc:17: error: no match for call to ‘(std::tr1::_Mem_fn<void (Class::*)(int)>) (Class&)’ 
/usr/include/c++/4.3/tr1_impl/functional:551: note: candidates are: _Res std::tr1::_Mem_fn<_Res (_Class::*)(_ArgTypes ...)>::operator()(_Class&, _ArgTypes ...) const [with _Res = void, _Class = Class, _ArgTypes = int] 
/usr/include/c++/4.3/tr1_impl/functional:556: note:     _Res std::tr1::_Mem_fn<_Res (_Class::*)(_ArgTypes ...)>::operator()(_Class*, _ArgTypes ...) const [with _Res = void, _Class = Class, _ArgTypes = int] 

Pourtant, le j'ai le même problème lorsque classe :: membre est surchargé par les membres qui prend différents arguments ...

Répondre

5

fonctions par défaut sont liés au moment de l'appel, mais ne peut pas être lié à une sorte d'emballage implicitement, à cause de la façon dont ils sont mis en œuvre. Lorsque vous passez &Class::member, mem_fn ne voit qu'un void (Class::*)(int) et ne peut pas voir l'argument par défaut. En utilisant tr1::bind, vous pouvez lier explicitement l'argument par défaut: std::tr1::bind(&Class::member, 0) ou vous pouvez l'utiliser comme mem_fn, mais vous ne pouvez pas faire les deux en un seul objet. Vous devrez écrire votre propre classe wrapper pour cela. En ce qui concerne les surcharges, vous devrez spécifier explicitement les arguments du modèle pour mem_fn afin que le bon pointeur de fonction soit sélectionné comme mem_fn<void(int)>(&Class::member).

3

Le La raison est que les arguments par défaut ne modifient pas le type de fonction d'une fonction.

mem_fn n'a aucun moyen de connaître la fonction exige seulement 1 argument, ou que le deuxième argument des fonctions est facultative, car toutes les connaissances qu'il obtient lui est donnée par le type de &Class::member (qui reste void(Class::*)(int)). Il nécessite donc un entier comme deuxième argument.

Si vous voulez passer l'adresse d'une fonction de membre surchargé, vous devez jeter à l'élément droit type pointeur de fonction:

static_cast<void(Class::*)()>(&Class::member) au lieu de simplement &Class::member, de sorte que le compilateur a un contexte de savoir quelle adresse est à prendre.

Modifier: coppro a une solution plus agréable comment fournir un contexte: std::tr1::mem_fn<void()>(&Class::member)

Questions connexes