Funktion als Template-Argument: wie zwischen 2 overloads unterschieden?
-
Hi!
Ich moechte einem boost::thread eine Funktion zum Ausfuehren mitgeben. Allerdings gibts von der Funktion 2 Overloads, und der GCC (4.1) kann anscheinend nicht entscheiden welche der beiden ich meine:
// das sind die funktionen: template<typename ParseReadsCallback> void parse_reads(const std::string& dir, ParseReadsCallback& callback); template<typename ParseReadsCallback> void parse_reads(const char* dir, ParseReadsCallback& callback); class ReadDetailsCallbacks { operator() (...) // callback fuer parse_reads ReadInfoMapPtr get_reads(const std::string& foo) { string dir = ... thread t1(parse_mapping_short<ReadDetailsCallbacks>, dir, ref(*this)); // <<<--- Hier passiert der Fehler! } };Und das ist die Fehlermeldung:
error: no matching function for call to 'boost::thread::thread(<unresolved overloaded function type>, std::string&, const boost::reference_wrapper<ReadDetailsCallbacks>)' include/boost/thread/detail/thread.hpp:199: note: candidates are: boost::thread::thread(boost::detail::thread_move_t<boost::thread>) include/boost/thread/detail/thread.hpp:147: note: boost::thread::thread() include/boost/thread/detail/thread.hpp:118: note: boost::thread::thread(boost::detail::thread_data_ptr) include/boost/thread/detail/thread.hpp:108: note: boost::thread::thread(boost::thread&) readdetails.cpp: In member function 'ReadInfoMapPtr ReadDetailsCallbacks::get_reads(const std::string&)':Wie kann ich dem GCC erklaeren, welche der 2 parse_reads()-overloads ich haben moechte?
EDIT: code-beispiel ausgeweitet damit die Fehlermeldungen mehr Sinn machen.
-
Du musst die parameter mit bind "binden" damit eine aufrufbare funktion entsteht.
Du brauchst ein boost::function<void()> das du übergibst.
-
evilissimo schrieb:
Du musst die parameter mit bind "binden" damit eine aufrufbare funktion entsteht.
Du brauchst ein boost::function<void()> das du übergibst.D.h. es gibt keinen Weg, wie man das mit "reinem C++" loest (d.h. ohne boost::function)?
-
Blue-Tiger schrieb:
evilissimo schrieb:
Du musst die parameter mit bind "binden" damit eine aufrufbare funktion entsteht.
Du brauchst ein boost::function<void()> das du übergibst.D.h. es gibt keinen Weg, wie man das mit "reinem C++" loest (d.h. ohne boost::function)?
natürlich gibt es den aber es ist umständlich ausserdem erwartet der thread constructor ein function object oder etwas das dorthin transformierbar ist. Das bedeutet deine Fehlermeldung.
-
Blue-Tiger schrieb:
Ich moechte einem boost::thread eine Funktion zum Ausfuehren mitgeben. Allerdings gibts von der Funktion 2 Overloads, und der GCC (4.1) kann anscheinend nicht entscheiden welche der beiden ich meine:
// das sind die funktionen: template<typename ParseReadsCallback> void parse_reads(const std::string& dir, ParseReadsCallback& callback); template<typename ParseReadsCallback> void parse_reads(const char* dir, ParseReadsCallback& callback); class ReadDetailsCallbacks { operator() (...) // callback fuer parse_reads ReadInfoMapPtr get_reads(const std::string& foo) { string dir = ... thread t1(parse_mapping_short<ReadDetailsCallbacks>, dir, ref(*this)); } };Du meintest sicherlich parse_reads und nicht parse_mapping_short, ja?
Ok, das ist halb so schlimm. Der Grund, warum's nicht geht ist, wie Du schon erkannt hast, dass das Funktionstemplate überladen ist. Daher bezeichnet parse_reads<ReadDetailsCallbacks> eine Menge von 2 Funktionsspezialisierungen. Eine solche Menge kann aber nicht für die "Template-Argument-Deduction" verwendet werden. "Template-Argument-Deduction" (TAD) muss hier aber stattfinden, weil Du einem Konstruktortemplate (in diesem Fall den vom boost::thread) die Template-Parameter nicht explizit mitgeben kannst. Lösen kann man das, indem Du Dir zB eine Zeigervariable für die Funktion anlegst:
void (*funptr)(const std::string&, ReadDetailsCallback) = parse_reads<ReadDetailsCallbacks>; // 1 thread t1(funptr, dir, ref(*this)); // 21. hier kann der Compiler aus der Menge der Funktionen die richtige rausfischen, die zum Funktionszeiger-Typen passt.
2. TAD funktioniert, da der Typ von funptr bekannt ist.Gruß,
SP
-
thx euch beiden!

Die Loesung von Sebastian funkioniert und erspart mir das Lesen der boost::bind doku
