Question

J'ai ce code:

#include <iostream>
#include <functional>

struct A
{
    int operator()(int i) const {
        std::cout << "F: " << i << std::endl;
        return i + 1;
    }
};

int main()
{
    A a;
    std::tr1::function<int(int)> f = std::tr1::ref(a);
    std::cout << f(6) << std::endl;
}

Le but est de passer l'objet foncteur par un reference_wrapper, de manière à éviter les appels inutiles copie de costructor. J'attends la sortie suivante:

F: 6
7

Il fonctionne correctement avec GCC> = 4.4.0, Visual Studio 2008 et coup de pouce en remplaçant std :: espace de noms TR1 avec boost. Il ne fonctionne pas seulement avec le nouveau Visual Studio 2010 Beta 2 Les cartes Express et Release Candidate.

Est-ce nouveau fonctionnalités C ++ buggé dans VS2010? Ou il y a une erreur ou une mauvaise utilisation dans le code?

Était-ce utile?

La solution

Je pense que je l'ai trouvé la raison. C'est ce que TR1 3.4/2 dit à propos result_of<T(A1, A2, ..., AN)>::type, utilisé dans la détermination du type de retour de reference_wrapper<T>::operator():

  

La mise en œuvre peut déterminer l'élément de type par tout moyen qui produit le type exact de l'expression f (t1, t2, ..., tN) pour les types donnés. [Note: L'intention est que les implémentations sont autorisés à utiliser la note spéciale crochets du compilateur]

Et le paragraphe 3:

  

Si F est pas un objet de fonction définie par la bibliothèque standard, et si soit la mise en oeuvre ne peut pas déterminer le type de l'expression f (t1, t2, ..., tN) ou si l'expression est mal formé, le la mise en œuvre doit utiliser le processus suivant pour déterminer le membre du type:

     
      
  • Si F est un type de classe peut-cv-qualifié sans membre nommé result_type ou si typename F::result_type est pas un type:      
        
    • Si N = 0 (aucun argument), le type est vide.
    •   
    • Si N> 0, le type est typename F::template result<F(T1, T2,..., TN)>::type
    •   
  •   

Le message d'erreur est un artefact d'essayer ces automne-backs. Fournir un typedef pour result_type à int et il devrait fonctionner, je pense. Notez que dans C++0x, ce qui est différent. Elle ne repose pas sur result_type ou un modèle de result, car il peut utiliser decltype.

Si avec <functional> il échoue avec MSVC10 en mode C ++ 0x, il sent comme un bug, je dirais. Mais peut-être quelqu'un d'autre sait ce qui se passe. Il peut (mais non garanti) travailler avec <tr1/functional> en mode C ++ 0x si cet en-tête choisit de prendre le chemin de decltype au lieu de ::result_type. Je typedef result_type - cette façon, je pense qu'il devrait toujours fonctionner indépendamment du fait que l'en-tête de tr1 est utilisé ou l'en-tête de c++0x.


Notez également que boost::tr1 dit dans sa documentation qu'il ne supporte pas l'opérateur d'appel de fonction (mais il supporte uniquement les conversions implicites à T&).

Autres conseils

Je rencontre un problème similaire ici: empêcher les copies inutiles de la foncteur de C des objets

Pour le compiler sur MSVC10, je devais tirer mon objet fonction de std :: unary_function.

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