Question

considérer ce code simple et inutile.

#include <iostream>

struct A {
    template<int N>
    void test() {
        std::cout << N << std::endl;
    }
};

int main() {
    A a;
    a.test<1>();
}

Il est un exemple très simple d'un modèle de fonction. Et si toutefois, je voulais remplacer A::test avec un operator() surchargé pour en faire un foncteur?

#include <iostream>

struct A {
    template<int N>
    void operator()() {
        std::cout << N << std::endl;
    }
};

int main() {
    A a;
    a<1>(); // <-- error, how do I do this?
}

Certes, si l'operator() a pris des paramètres qui étaient en fonction du modèle, le compilateur pourrait en déduire le modèle. Mais je ne peux pas comprendre la syntaxe appropriée pour spécifier les paramètres modèle avec un foncteur sans paramètre.

Y at-il une bonne façon de le faire?

De toute évidence, ce code fonctionnerait car il contourne la syntaxe foncteur:

a.operator()<1>();

mais que des défaites un peu le but de celui-ci étant un foncteur :-P.

Était-ce utile?

La solution

Il n'y a pas une autre façon « directe » Je sais autre que:

 a.operator()<1>();
syntaxe

. Si vous êtes ouvert à changer le code, le déplacement du paramètre de modèle à la classe fonctionnerait, ou en utilisant un (coup de pouce | TR1) :: bind faire un. (Coup de pouce | TR1) :: objet fonction

Autres conseils

Vous ne pouvez appeler

a.operator()<1>();

mais cela ne comptez pas utiliser un foncteur. Foncteurs ont besoin d'un opérateur non modèle (), car ils doivent pouvoir être appelé varname () et ne fonctionneront pas avec votre code.

Pour faire un vrai foncteur changer votre code une classe de modèle (foncteurs sont des classes):

#include <iostream>

template<int N>
struct A {
    void operator()() {
        std::cout << N << std::endl;
    }
};

int main() {
    A<1> a;
    a();
}

Vous essayez de passer un paramètre de modèle à une instance d'un objet, qui, autant que je sache, n'est pas autorisé. Vous ne pouvez transmettre des paramètres de modèles aux fonctions de modèle ou d'objets de modèle.

a.test (<1>); et a.operator () <1> (); travailler parce qu'ils servent de modèle fonctionne.

Utiliser boost :: bind (consultez les bibliothèques Boost) pour fixer cependant.

struct A {
    void operator()(int n) {
        std::cout << n << std::endl;
    }
};

int main(int argc, char* argv[]) {
    A a;
    boost::function<void()> f = boost::bind<void>(a, 1);
    f(); // prints 1

    return 0;
}

Et vous n'avez même pas gâcher avec des modèles!

Vous êtes coincé. Avez-vous envisagé quelque chose comme

struct A {
    template<int N>
    struct B
    {
        void operator()()
        { std::cout << N << std::endl; }
    };

    template<int N>
    B<N> functor() {return B<N>();}
};

int main()
{
    A a;
    a.functor<1>()();
}

Non, il n'y a pas moyen de contourner cela. Comme vous l'avez dit, vous devez soit appeler explicitement l'opérateur (qui contrecarre le but), ou les arguments de modèle doit pouvoir être déduit par le compilateur.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top