std :: avant de transmettre un funciton

voix
0

Je le code suivant ne compile pas tout simplement, en particulier après est transmis par std :: avant

struct TestParent
{
    template< typename Fn >
    bool test( Fn&& fn )
    {
        //.. do something
        //.. check some condition
        bool someCondition = true;
        if ( someCondition )

        {
            //this call works!
            return fn();
        }

        return testAtNextLevel( std::forward< Fn >( fn ) );
    }

    template < typename Fn >
    bool testAtNextLevel( Fn&& fn )
    {
        if ( (this->*fn() )
        {
             return true;
        }

         //... test some more
         return true;
     }
}

struct TestChild: public TestParent
{
     bool thisTestOk();
     bool testAll();
}

bool TestChild::thisTestOk()
{
     return true;
}

bool testAll()
{
    auto myFunc = std::bind( &TestChild::thisTestOk, this );
    return test( myFunc );
}

Lors de la compilation, je reçu ce message d'erreur:

error: no match for 'operator->*' (operand types are 'TestParent*' and 'std::_Bind<std::_Mem_fn<bool (TestChild::*)()>(TestChild*)>')
 if ( (this->*fn)() )

Toute personne a des idées pour expliquer pourquoi après avoir traversé std :: En avant, la fonction juste ne peut pas être appelé? A la classe de base, juste avant l'appel « testAtNextLevel », si certaines conditions sont remplies, nous pouvons simplement appeler le passé en fonction, mais pas après est transmis à une autre fonction de modèle?

Créé 07/11/2018 à 20:22
source utilisateur
Dans d'autres langues...                            


1 réponses

voix
1

Avec tous ces modèles et autodéclarations, il devient facile de perdre la trace de ce type de données que vous avez affaire. Commençons près du bas de votre code:

auto myFunc = std::bind( &TestChild::thisTestOk, this );

Qu'est - ce myFunc? Bien que le type de retour std::bindest officiellement non spécifiée, son utilisation est indiquée (voir, par exemple, cppreference.com ). Appeler cette valeur renvoyée en tant que fonction est équivalente à l' invocation thisTestOk()de son argument lié à seul this.

Autrement dit, le pointeur-to-caché TestChildargument (présent dans l' ensemble de TestChild« s fonctions membres non statiques) a été remplacé par this, ce qui a pour effet de convertir une fonction membre à une fonction non-membre. Maintenant , regardons comment vous invoquez cette enveloppe fonction non-membre.

Au sein de test()cette enveloppe est invoquée par l' intermédiaire return fn(). Elle est invoquée en fonction, et fonctionne comme prévu.

Au sein de testAtNextLevel()cette enveloppe est invoquée par l' intermédiaire this->*fn(). Cette enveloppe non-membre de fonction est invoquée comme un pointeur à élément de fonction, qui est une erreur. Pour être tout simplement devrait le faire fonctionner syntaxiquement, l'invocation fn(), comme il était test(). Si vous voulez vraiment passer outre l'objet lié et utiliser thiscomme argument caché pour fn(), vous devez passer quelque chose de différent comme argument testAtNextLevel(), probablement un pointeur à membre (et il devrait être un pointeur-to- TestParent-membre, pas un pointeur-to- TestChild-Member).

Créé 07/11/2018 à 22:58
source utilisateur

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more