Bug im VC++7 (Operator Lookup)
-
Nachtrag:
der VC++6 bringt den selben operator<< not found Fehler.Ich hatte vorher irrtuemlich mit dem Intel Compiler kompiliert.
-
Jetzt will er keine der Beiden Versionen mehr... Sehr komisch.
Hat jemand eine Idee?
-
Ups. Ich hatte grade in 'nem anderen Forum was gelesen. Und irgendwie die beiden Probleme jetzt durcheinander gebracht. Sorry, vergiss einfach, was ich geschrieben hab.
OK, muss ich selbst zu Hause mal testen.
-
wenn du anstatt den String zu templatisieren, den string::value_type templatisierst (gibts das wort eigentlich
) , funktioniert es:
namespace foo1 { template<class Ch> class C { public: std::basic_ostream<Ch,std::char_traits<Ch> >& writeAt(std::basic_ostream<Ch, std::char_traits<Ch> >& stream) const { stream<<"xyz"<<endl; return stream; } }; template<class Ch> inline std::basic_ostream<Ch, std::char_traits<Ch> >& operator<<(std::basic_ostream<Ch, std::char_traits<Ch> >& out, C<Ch> const& obj) { return obj.writeAt(out); //return out; //mit dieser Zeile wuerde es gehen } }
weiß natürlich nicht ob das akzeptabel für dich ist..
mfg shady
-
Leider ist das nicht moeglich
Denn es geht hauptsaechlich um die Implementierung von StringT und weniger um den char-TypenAber danke, dass du dir die Muehe machst mir zu helfen.
-
Schade. Einen anderen Workaround seh ich jetzt leider nicht.
Außer Microsoft zu boykotieren;)cu
-
Hallo Shade,
das Problem ist nicht, dass er den operator nicht finden, sondern dass er den Typ von StringT nicht automatisch herleiten kann (das gilt zumindest für den VC 6.0).Das Problem lässt sich auf folgendes Minimalbeispiel reduzieren:
#include <iostream> #include <string> using namespace std; template<class T> void func(basic_ostream<typename T::value_type, typename T::traits_type>& o, const T& s) { } int main() { func(cout, string()); }
Die abhängigen Namen T::value_type und T::traits_type verwirren ihn hier so sehr, dass er T nicht herleiten kann.
Interessant wird's, wenn du die Parameter vertauschst:
template<class T> void func(const T& s, basic_ostream<typename T::value_type, typename T::traits_type>& o) { }
In diesem Fall hält er T für mehrdeutig (string oder char). Wie er auf diese Idee kommt ist mir unklar. char ist eindeutig kein gültiger Kandidat (es sei denn irgendjemand hat heimlich dem Typ char ein internes typedef spendiert). Scheinbar wertet er T::value_type aus und nimmt das Ergebnis dann als mögliches T.
Ein Workaround fällt mir jetzt auf die schnelle nicht ein. Da es sich auch noch um einen Operator handelt, sind die Möglichkeiten wohl auch sehr limitiert (viele Tricks erfordern weitre Dummy-Parameter). Sieht auf jeden Fall nach einer Herausforderung aus. Leider habe ich im Moment nicht die Zeit mich dieser anzunehmen.
Das einzige was ich dir empfehlen kann, ist eine ausführliche Suche in den boost-Quellen bzw. auf der boost-Mailinglist (vielleicht irgendwas mit Dependent typename oder eine Suche nach der Fehlernummer C2784).
Ich weiß, alles nicht sehr hilfreich, was ich hier schreibe.
-
HumeSikkins schrieb:
Das einzige was ich dir empfehlen kann, ist eine ausführliche Suche in den boost-Quellen bzw. auf der boost-Mailinglist (vielleicht irgendwas mit Dependent typename oder eine Suche nach der Fehlernummer C2784).
Thx, aber boost habe ich schon durchsucht, werde aber wohl intensiver suchen...
Ich weiß, alles nicht sehr hilfreich, was ich hier schreibe.
Oh doch! Du hast mir wenigstens sagen koennen woran er scheitert.
Das ist schonmal eine Hilfe.Danke
-
Das bringt mich auf eine billig Loesung:
template<class StringT> class C { public: std::basic_ostream<typename StringT::value_type, typename StringT::traits_type>& writeAt(std::basic_ostream<typename StringT::value_type, typename StringT::traits_type>& stream) const { return stream; } }; template<typename CharT, class TraitsT, class StringT> inline std::basic_ostream<CharT, TraitsT>& operator<<(std::basic_ostream<CharT, TraitsT>& out, C<StringT> const& obj) { return obj.writeAt(out); }
Was haltet ihr davon?
Wenn StringT::value_type und CharT nicht gleich sind, dann ist die Fehlermeldung zwar n bisschen doof, aber dafuer funktioniert es.Ich werde aber trotzdem mal gruendlich boost durchsuchen.
-
Wenn StringT::value_type und CharT nicht gleich sind, dann ist die Fehlermeldung zwar n bisschen doof
Da kannst du doch ein schönes static_assert für nehmen.