2010-08-02 5 views
5

Je veux mettre le résultat de cette:std :: tr1 :: mem_fn type de retour

std::tr1::mem_fn(&ClassA::method); 

A l'intérieur d'une variable, quel est le type de cette variable?

Cela va ressembler à quelque chose comme ceci:

MagicalType fun = std::tr1::mem_fn(&ClassA::method); 

De plus, quel est le type de résultat std::tr1::bind?

Merci!

Répondre

4

Les types de retour des deux codes std::tr1::mem_fn et std::tr1::bind ne sont pas spécifiés.

Vous pouvez stocker le résultat de std::tr1::bind dans un std::tr1::function:

struct ClassA { 
    void Func() { } 
}; 

ClassA obj; 
std::tr1::function<void()> bound_memfun(std::tr1::bind(&ClassA::Func, obj)); 

Vous pouvez également stocker le résultat de std::tr1::mem_fn dans un std::tr1::function:

std::tr1::function<void(ClassA&)> memfun_wrap(std::tr1::mem_fn(&ClassA::Func)); 
+0

Je suis en train d'utiliser 'std :: tr1 :: fonction = amusant std :: tr1 :: mem_fn (& ClassA :: méthode);' mais il ne Compiler, qu'est-ce qui ne va pas? – Tarantula

+0

@Tarantula: L'objet appelable renvoyé par 'mem_fn' prend une référence, pas un pointeur. Voir la réponse mise à jour. –

+0

Ca ne marche toujours pas, mon prototype pour Func est: virtual void Func (argument MyType *) = 0; – Tarantula

2

Le type de retour de mem_fn et bind est non spécifié. Cela signifie qu'en fonction des arguments, un type d'objet différent est renvoyé, et que la norme ne prescrit pas les détails sur la façon dont cette fonctionnalité doit être implémentée.

Si vous voulez savoir quel type est dans un cas particulier avec une implémentation de bibliothèque particulière (pour un intérêt théorique, j'espère), vous pouvez toujours provoquer une erreur et obtenir le type du message d'erreur. E.g:

#include <functional> 

struct X 
{ 
    double method(float); 
}; 

int x = std::mem_fn(&X::method); 

9 Untitled.cpp cannot convert 'std::_Mem_fn<double (X::*)(float)>' to 'int' in initialization 

Dans ce cas, notez que le nom du type est réservé à un usage interne. Dans votre code, vous ne devez rien utiliser avec un caractère de soulignement (et une lettre majuscule).

En C++ 0x, je suppose que le type de retour serait auto :)

auto fun = std::mem_fn(&ClassA::method); 
0

La fonction pourrait être mise en œuvre de la manière suivante (vous voyez donc aussi le type de retour): Vous pouvez essayer morceau de code ici http://webcompiler.cloudapp.net/. Malheureusement, il utilise des modèles variés https://en.wikipedia.org/wiki/Variadic_template qui ne sont qu'une partie de la norme C++ 11.

#include <iostream> 
#include <string> 

template <class R, class T, class... Args > class MemFunFunctor 
{ 
    private: 
    R (T::*mfp)(Args...); //Pointer to a member function of T which returns something of type R and taking an arbitrary number of arguments of any type 

public: 
    explicit MemFunFunctor(R (T::*fp)(Args...)):mfp(fp) {} 

    R operator()(T* t, Args... parameters) 
    { 
     (t->*mfp)(parameters...); 
    } 

}; 

template <class R,class T, class... Args> MemFunFunctor<R,T,Args... > my_mem_fn(R (T::*fp)(Args...)) 
{ 
    return MemFunFunctor<R,T,Args... >(fp); 
} 


class Foo //Test class 
{ 
    public: 
     void someFunction(int i, double d, const std::string& s) 
     { 
      std::cout << i << " " << d << " " << s << std::endl; 
     } 
}; 


int main() //Testing the above code 
{ 

    Foo foo; 
    auto f = my_mem_fn(&Foo::someFunction); 

    f(&foo, 4, 6.7, "Hello World!"); //same as foo.someFunction(4, 6.7, "Hello World!"); 

    return 0; 
} 
+0

Pourriez-vous fournir quelques commentaires/description pour votre code? – kvorobiev

Questions connexes