ne fournit pas d'erreur d'opérateur d'appel" lors de la tentative de validation de la fonction de retour de la fonction - Retrouvez les réponses et les commentaires concernant cette question" />
J'essaie d'écrire une fonction qui prendra un agenceur comme argument, appelez le fonctionnaire, puis renvoyé sa valeur de retour enveloppée dans un Les éléments suivants refusent Compiler et je suis tout à fait des idées. Je reçois "std :: vecteur boost :: Shared_ptr code>.
#include <boost/make_shared.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <string>
#include <vector>
std::vector< std::string > foo()
{
std::vector< std::string > vec;
return vec;
}
template< typename T >
boost::shared_ptr< T > ReturnValueAsShared(
boost::function< T() > func )
{
return boost::make_shared< T >( func() );
}
int main()
{
auto f = boost::bind( ReturnValueAsShared< std::vector< std::string > >,
foo );
f();
} // main
3 Réponses :
la réécriture complète, la réponse originale était incorrecte. em> Comme je ne savais pas au début ce qui se passait ici, j'ai fait une analyse. Je le garde pour une référence future; Voir la solution ci-dessous pour éviter le problème. P> qui à mon avis Traduit comme suit: p> Donc, de sorte que ce que vous attendez que ce code fasse est de transmettre l'argument à la fonction, juste comme ça. Mais pour que cela fonctionne, l'expression Ceci sera évaluer em> la fonction nullaire, au lieu de passer sur. Donc, au lieu d'un objet renvoyant un vecteur, l'argument est maintenant un Vecotr. Les étapes suivantes tenteront de convertir cela en une fonction édité à nouveau: em> de analyse d'erreur h1>
bind.hpp code> est-ce: p>
a [base_type :: a1 _] code> devrait être de type
bottes: _bi :: valeur
Boost :: _ BI :: BIND_T CODE>. Donc, au lieu du fonctionnement étant passé comme argument, une version surchargée spéciale est appelée: p>
boost :: fonction code> et échouer. P>
solution canonique h1>
Il ressemble à cette manipulation spéciale de Lié imbriquée est conçu comme une fonctionnalité. Parler sur #Boost code> avec les utilisateurs ZAO et Heller, je sais maintenant qu'il existe une fonction
protège code> pour contrer ces effets. Donc, la solution canonique à ce problème semble être la suivante: p>
Non, la valeur renvoyée est un foncteur qui, lorsqu'il est exécuté renvoie un partagé_ptr code>. Si je remplace
f () code> avec
(* f) () code>, je reçois à juste titre une erreur de compilateur qui se plaint que
f code> n'est pas de type pointeur .
Ok, vous êtes rythmé, le problème est un niveau plus profond. Il me semble que Bind code> n'a pas de surcharge pour
partagé_ptr code>, il suppose donc un objet de fonction par défaut. Mais comme
partagé_ptr code> ne fournit pas d'opérateur d'appel, les choses échouent.
Um, Bind code> n'a pas besoin d'une surcharge pour
partagé_ptr code>, c'est un modèle. En outre, l'erreur se plaint que
vecteur
partagé_ptr code>.
Pour votre version modifiée: il semble manquer qu'il y a un boost :: lid ( code> devant
retourvalueasshared code> dans
auto f = ... code >. En tout point, le code essaie d'appeler
partagé_ptr <...> :: opérateur () code>.
OK, que sur le vecteur
@LUCAS: Deuxième match majeur, réécrit complètement le code. Obtenu ça marche.
@LUCAS, j'ai encore modifié la réponse; Maintenant, il inclut la solution canonique conçue dans la documentation de Boost.
Certaines constructions (telles que (ceci elle-même ne fonctionne pas pour moi, mais ça marche si vous Utilisez les constructions correspondantes lidez code>) renvoient des types intermédiaires "expression" que vous ne voulez réellement capturer sur le nez. Dans ce cas, vous ne devez pas capturer le type via
auto code> et vous devrez peut-être spécifier des conversions explicites, car sinon il n'y a pas une chaîne de conversion unique unique à l'utilisateur unique. Dans votre cas, ajoutez la conversion explicite de l'expression de liaison à la fonction
code>:
std code>.) p> p>
Emballage mon deuxième Bind code> Appelez avec un casting
boost :: Fonction
Boost :: Protéger est la voie à suivre:
int main() { auto f = boost::bind( ReturnValueAsShared< std::vector< std::string > >, boost::protect(boost::bind( foo, std::string("a") ) ) ); f(); } // main
Cette réponse pourrait être améliorée par une explication de ce que boost :: protège code> est ce qu'il fait et peut-être un lien vers les documents qui le décrivent encore plus en détail.
Veuillez simplifier le problème et fournir un code d'exemple minimal (non) de travail.
@Kerreksb the erreur est
std :: vecteur ne fournit pas d'opérateur d'appel code> lorsque j'essaie de l'utiliser comme
retourvalueasshared > code>.
@Konradrudolph Je vais essayer de le minimiser.
@KonRADRUDOLPH Cas d'essai ajouté.
Le paramètre
boost :: fonction func code> - peut-être qu'il devrait avoir
t code> au lieu de
t () code>?
@ user1071136 Non, ce qui échoue à compiler également (comme il le devrait), car ce n'est pas la façon dont la fonction de boost :: La fonction accepte les définitions de la fonction. Voir Boost.function Docs. A >
HM, on dirait que le boost n'est tout simplement pas si bon. La version
std code> de cela fonctionne dès que vous ajoutez une conversion explicite sur
std :: Fonction> ()> code> autour du
lier code> appel.
@Kerreksb es-tu en train de dire que c'est un bug de boost? Je m'appuyais vers cette conclusion ...
@Kerreksb j'ai essayé d'envelopper le deuxième
appel code> appel avec
boost :: Fonction ()> () code> pour le jeter et il compile. Kerrek, faites votre commentaire une réponse et je vais l'accepter car cela m'a conduit sur le chemin droit (je viens d'utiliser la version
boost :: code> de ce que vous avez dit).
Comportement étrange ... LiveWorkspace.org/code/2C2B09F708A6D481E06AA39F2EDA632F compilateur Essayez de convertir Int à Boost :: Fonction.