"<Klassenname> keine call-operator" Fehler beim wrap-Funktion return Wert
Ich versuche, eine Funktion schreiben, die nimmt einen Funktor als argument aufrufen des funktors und dann wieder seinen Wert zurück, eingewickelt in ein boost::shared_ptr
.
Folgende weigert sich zu kompilieren, und ich bin alle Ideen. Bekomme ich "std::vector< std::string > keine call-operator" (rund). Ich bin mit Clang 3.1, auf Mac OS X.
template< typename T >
boost::shared_ptr< T > ReturnValueAsShared(
boost::function< T() > func )
{
return boost::make_shared< T >( func() );
}
Dies ist der Kontext, in dem ich versuche, es zu benutzen:
make_shared< packaged_task< boost::shared_ptr< std::vector< std::string > > > >(
bind( ReturnValueAsShared< std::vector< std::string > >,
bind( [a function that returns a std::vector< std::string >] ) ) );
EDIT: Hier ist eine komplette Selbstversorger-test-Fall. Dieser code nicht kompilieren, mit dem gleichen Fehler, und für das Leben von mir ich kann nicht sehen, was falsch ist:
#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::string a )
{
std::vector< std::string > vec;
vec.push_back( a );
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 > >,
boost::bind( foo, std::string("a") ) );
f();
} //main
Und hier ist die Fehlerausgabe:
In file included from testcase.cpp:3:
In file included from /usr/local/include/boost/function.hpp:64:
In file included from /usr/local/include/boost/preprocessor/iteration/detail/iter/forward1.hpp:47:
In file included from /usr/local/include/boost/function/detail/function_iterate.hpp:14:
In file included from /usr/local/include/boost/function/detail/maybe_include.hpp:13:
/usr/local/include/boost/function/function_template.hpp:132:18: error: type 'std::vector<std::basic_string<char>, std::allocator<std::basic_string<char> > >' does not provide a call operator
return (*f)(BOOST_FUNCTION_ARGS);
^~~~
/usr/local/include/boost/function/function_template.hpp:907:53: note: in instantiation of member function 'boost::detail::function::function_obj_invoker0<std::vector<std::basic_string<char>, std::allocator<std::basic_string<char> > >, std::vector<std::basic_string<char>, std::allocator<std::basic_string<char> > > >::invoke' requested here
{ { &manager_type::manage }, &invoker_type::invoke };
^
/usr/local/include/boost/function/function_template.hpp:722:13: note: in instantiation of function template specialization 'boost::function0<std::vector<std::basic_string<char>, std::allocator<std::basic_string<char> > > >::assign_to<std::vector<std::basic_string<char>, std::allocator<std::basic_string<char> > > >' requested here
this->assign_to(f);
^
/usr/local/include/boost/function/function_template.hpp:1042:5: note: in instantiation of function template specialization 'boost::function0<std::vector<std::basic_string<char>, std::allocator<std::basic_string<char> > > >::function0<std::vector<std::basic_string<char>, std::allocator<std::basic_string<char> > > >' requested here
base_type(f)
^
/usr/local/include/boost/bind/bind.hpp:243:43: note: in instantiation of function template specialization 'boost::function<std::vector<std::basic_string<char>, std::allocator<std::basic_string<char> > > ()>::function<std::vector<std::basic_string<char>, std::allocator<std::basic_string<char> > > >' requested here
return unwrapper<F>::unwrap(f, 0)(a[base_type::a1_]);
^
/usr/local/include/boost/bind/bind_template.hpp:20:27: note: in instantiation of function template specialization 'boost::_bi::list1<boost::_bi::bind_t<std::vector<std::basic_string<char>, std::allocator<std::basic_string<char> > >, std::vector<std::basic_string<char>, std::allocator<std::basic_string<char> > > (*)(std::basic_string<char>), boost::_bi::list1<boost::_bi::value<std::basic_string<char> > > > >::operator()<boost::shared_ptr<std::vector<std::basic_string<char>, std::allocator<std::basic_string<char> > > >, boost::shared_ptr<std::vector<std::basic_string<char>, std::allocator<std::basic_string<char> > > > (*)(boost::function<std::vector<std::basic_string<char>, std::allocator<std::basic_string<char> > > ()>), boost::_bi::list0>' requested here
BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0);
^
testcase.cpp:27:4: note: in instantiation of member function 'boost::_bi::bind_t<boost::shared_ptr<std::vector<std::basic_string<char>, std::allocator<std::basic_string<char> > > >, boost::shared_ptr<std::vector<std::basic_string<char>, std::allocator<std::basic_string<char> > > > (*)(boost::function<std::vector<std::basic_string<char>, std::allocator<std::basic_string<char> > > ()>), boost::_bi::list1<boost::_bi::bind_t<std::vector<std::basic_string<char>, std::allocator<std::basic_string<char> > >, std::vector<std::basic_string<char>, std::allocator<std::basic_string<char> > > (*)(std::basic_string<char>), boost::_bi::list1<boost::_bi::value<std::basic_string<char> > > > > >::operator()' requested here
f();
^
1 error generated.
Hier sind einige weitere Anhaltspunkte. Der folgende code kompiliert werden, ganz gut, aber das hilft mir nicht denn dies ist nicht der code, den ich will 🙂
#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
- Vereinfachen Sie das problem und bieten eine minimale (nicht-)Arbeit Beispiel-code.
- Was ist der Fehler???
- Der Fehler ist
std::vector<std::string> does not provide a call operator
wenn ich versuche, es zu benutzen, wieReturnValueAsShared< std::vector< std::string > >
. - Ich werde versuchen, das zu minimieren.
- Testfall Hinzugefügt.
- Die parameter
boost::function< T() > func
- vielleicht sollte es habenT
stattT()
? - Nein, das nicht kompiliert werden kann, als auch (wie es soll) da, das ist nicht die Art und Weise, dass boost::function übernimmt die Funktion Definitionen. Siehe die Boost.Die Funktion docs.
- Hm, sieht aus wie Boost einfach nicht so gut. Die
std
version von dies funktioniert, sobald Sie eine explizite Konvertierung instd::function<std::vector<std::string>>()>
rund um diebind
nennen. - Sie sagen, dies ist ein Boost bug? Ich lehnte gegenüber, dass der Abschluss...
- Ich habe versucht, das einwickeln der zweiten
bind
Anruf mitboost::function< std::vector< std::string >() >()
zu werfen und es jetzt kompiliert. Kerrek, machen Sie Ihrem Kommentar eine Antwort und ich werde es akzeptieren, da führte er mich auf den richtigen Pfad (ich habe gerade verwendet dieboost::
version von dem, was Sie sagte). - Seltsames Verhalten... liveworkspace.org/code/2c2b09f708a6d481e06aa39f2eda632f compiler versuchen zu konvertieren, int, boost::function<int()>.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Einige Konstruktionen (wie
bind
) return intermediate "Ausdruck" - Typen, die Sie nicht wirklich wollen, zu erfassen, auf die Nase. In diesem Fall, darf man Sie nicht erfassen über den Typ mitauto
, und geben Sie explizite Umwandlungen werden, da sonst, gibt es nicht eine einmalige, single-user-definierten conversion-Kette. In Ihrem Fall ist, fügen Sie die explizite Konvertierung von bind-Ausdruck anfunction
:(Das sich nicht wirklich für mich arbeiten, aber es funktioniert, wenn Sie die entsprechenden
std
Konstruktionen.)bind
Anruf mit einer Besetzungboost::function< std::vector< std::string >() >(...)
macht alles richtig funktioniert. Danke für die info.boost::schützen, ist der Weg zu gehen:
Dies ist so sauber, wie es bekommen kann.
boost::protect
ist, was es tut, und vielleicht ein link zu den docs, beschreibe es noch genauer.Komplette Neuentwicklung, ursprüngliche Antwort war falsch.
Fehleranalyse
Da ich nicht wusste zunächst, was schief läuft hier, habe ich einige Analyse. Ich halte es für die Zukunft; Sie sehen die Lösung unten, wie das problem zu vermeiden.
bind.hpp
tut:die meiner Meinung nach übersetzt so:
Also, was würden Sie erwarten, dass dieser code zu tun ist, übergeben Sie das argument an die Funktion, so wie es ist. Aber für diese zu arbeiten, den Ausdruck
a[base_type::a1_]
müsste der Typboots:_bi::value<T>
, in der Erwägung, dass der unverpackte Typboost::_bi::bind_t
. Anstatt also den Funktor übergeben als argument, eine spezielle überladene version wird aufgerufen:Diese wird bewerten die nullary Funktion, anstatt es weiter zu geben. Also statt eines Objekts Rückgabe eines Vektors, das argument ist jetzt ein vecotr. Die nachfolgenden Schritte werden versuchen, zu konvertieren, dass zu einem
boost::function
- und scheitern.Kanonische Lösung
Bearbeitet noch einmal:
Es sieht aus wie diese Besondere Behandlung von verschachtelte bindet bestimmt ist als eine Funktion. Reden auf
#boost
mit Benutzer Zao und heller, ich weiß jetzt, dass es eineprotect
Funktion gegen diese Effekte. So ist die kanonische Lösung für dieses problem scheint Folgendes zu sein:shared_ptr
. Wenn ich ersetzenf()
mit(*f)()
ich zu Recht ein compiler-Fehler, der sich beschwert, dassf
ist nicht vom Typ Zeiger.bind
hat keine überladung fürshared_ptr
, so nimmt es eine function-Objekt, das standardmäßig. Aber wieshared_ptr
nicht, eine call operator, Dinge scheitern.bind
muss nicht eine überlastung fürshared_ptr
, es ist eine Vorlage. Auch die Fehlermeldung beschwert sich darüber, dassvector<string>
nicht über ein call operator, keineshared_ptr
.boost::bind(
vorReturnValueAsShared
imauto f = ...
. Zu keinem Zeitpunkt nimmt den code versuche zu nennenshared_ptr<...>::operator()
.vector<string>
ist ein guter Punkt. Ich lasse meine Antwort, um für die Zeit Wesen, als eine Dokumentation der fehlgeschlagenen Bemühungen, aber erwarten, um zu löschen, es irgendwann noch einmal eine richtige Antwort gefunden werden konnte.