vergleichoperator zur compilierzeit aufrufen
-
hi,
ich versuche zur compilierzeit herauszufinden ob ein typ einen vergleichoperator definiert hat.Ich habe es schon hingekriegt, dass es zur laufzeit funktioniert:
#include <iostream> struct A{ }; struct AA { bool operator==(const AA& )const { return true; } }; struct AAA { friend bool operator==(const AAA&, const AAA&){ return true; } }; namespace __hidden_ { struct CNoType7Byte{ char dummy[7]; }; template <typename T> CNoType7Byte operator==(const T&, const T&) { return CNoType7Byte(); } } // namespace __hidden_ template <typename T> struct CIsComparable { static bool Result() { using namespace __hidden_; // hier ist das problem, denn hier werden // Objektinstanzen erstellt. T t; // Geht es irgendwie die typen an sich zu vergleichen. return sizeof(t == t) != sizeof(CNoType7Byte); } }; template <typename T> inline bool IsComparable(){ return CIsComparable<T>::Result(); } int main() { std::cout << IsComparable<int>() << std::endl; // gibt 1 std::cout << IsComparable<A>() << std::endl; // gibt 0 std::cout << IsComparable<AA>() << std::endl; // gibt 1 std::cout << IsComparable<AAA>() << std::endl; // gibt 1 }Oder weiß jemand dafür eine bessere Möglichkeit?
-
Da du sowieso mit Templates arbeitest, kannst du ja einfach "behaupten", daß der verwendete Typ vergleichbar ist - wenn du etwas unvergleichbares als Parameter mitgibst, wird dir der Compiler schon einen "no matching function" entgegenwerfen.
-
das problem ist, dass ich dann eine alternative funktion aufrufen möchte, wenn die typen nicht vergleichbar sind. Eine fehlermeldung bringt mir da recht wenig.
Natürlich funktioniert mit Code von mir oben, auch wenn ich erst zur laufzeit herausfinde, ob der typ vergleichbar ist oder nicht. aber zur compilierzeit wäre es doch viel schöner, finde ich.
-
frager schrieb:
das problem ist, dass ich dann eine alternative funktion aufrufen möchte, wenn die typen nicht vergleichbar sind. Eine fehlermeldung bringt mir da recht wenig.
Natürlich funktioniert mit Code von mir oben, auch wenn ich erst zur laufzeit herausfinde, ob der typ vergleichbar ist oder nicht. aber zur compilierzeit wäre es doch viel schöner, finde ich.
Neee - auch in Deinem Code steckt die Information, bereits zur Compilezeit ... Du wertest sie aber erst zur Laufzeit aus - was ich persönlich "quatschig" finde.

Mein Vorschlag: Mach bereits die "Auswahl der richtigen Funktion" zur Compilezeit (z.B. via overloading oder templates).
Gruß,
Simon2.
-
Simon2 schrieb:
Mein Vorschlag: Mach bereits die "Auswahl der richtigen Funktion" zur Compilezeit (z.B. via overloading oder templates).
So, und kannst du die Realisierung als Quelltext dazu posten? Ich sitze an dem Problem nämlich schon den einen oder anderen Tag. Mir fällt da einfach nix zu ein.
-
Die Grundkonstruktion arbeitet auch zur Compilezeit, du mußt jetzt nur einen Weg finden, sie auch zur Compilezeit auszuwerten:
template <typename T> struct CIsComparable { static bool Result() { using namespace __hidden_; // hier ist das problem, denn hier werden // Objektinstanzen erstellt. T t; // Geht es irgendwie die typen an sich zu vergleichen. return sizeof(t == t) != sizeof(CNoType7Byte); } enum{value=(sizeof(T()==T()) != sizeof(CNoType7Byte))}; }; template<typename T,bool comp> struct compare { bool operator()(const T& l,const T& r) { return l==r; } }; template<typename T> struct compare<T,false> { bool operator()(const T& l,const T&r) { return my_special_compare(l,r); } }; template<typename T> void do_something(...) { compare<T,CIsComparable<T>::value> cmp; //alle Elementvergleiche verwenden cmp(x,y) anstelle von x==y }PS: Schonmaldie Boost-Bibliothek durchforstet? Afair gibt es dort auch ein Paket, mit dem du wichtige Typ-Eigenschaften (Default-bonstruierbar, vergleichbar,...) checken kannst.
-
Hi,
oder einfach, wie CStoll es zuerst vorgeschlagern hat:
operator==(TypA const&, TypB const&)einfach benutzen ... der Compiler sagt Dir schon (und zwar nicht ungenauer oder unzuverlässiger als alle template-Versuche), wenn es keinen gibt.Gruß,
Simon2.
-
CStoll schrieb:
enum{value=(sizeof(T()==T()) != sizeof(CNoType7Byte))};Danke, das war was ich gesucht habe. War irgendwie viel zu sehr darauf verbort, dass == auch immer true zurückgeben muss.

Bei boost habe ich geschaut, hab nix gefunden. Kann sein, dass ich da was übersehen habe, benutze boost eigentlich selbst nie.