Funktion abhängig der Größe eines Templateparameters überladen
-
CStoll schrieb:
Da würde ich im Zweifelsfall lieber ein paar Prozessortakte für die Dereferenzierung in Kauf nehmen als mir mit derartigen Problemen meine Programme zu zerstören.
Also geht's nicht sinnvoll, die paar Takte zu sparen zu automatosieren. Schade. C++ ist dahingehend eine schlechte Spache.

-
Kennst du einen Weg zu fragen, ob ein gegebener Typ einen trivialen Kopierkonstruktor hat? Wenn ja, könnte man die obengenannten enable_if-Konstrukionen darauf ansetzen.
-
CStoll schrieb:
Es gibt genug Klassen, die (aus Sicht des sizeof()) klein sind, aber trotzdem nicht als Kopie übergeben werden können oder sollten sollten
Gute Einwände, CStoll.
Wenn man etwas defensiver vorgeht, kann man diese Probleme vermeiden. Beschränkt man sich auf skalare Typen, sind die meisten Fälle sind dann trotzdem noch abgedeckt. Mit der Metafunktion
is_scalaraus Boost.TypeTraits (oder TR1/C++0x-Äquivalenten) kann diese Typeigenschaft geprüft werden. Das grösste Problem sehe ich hier bei Iteratoren, für diese müsste man allenfalls eine Spezialisierung einrichten. Vielleicht aber besser bei einem eigenen Template als direkt beiis_scalar.Ist halt immer die Frage, wie weit man mit der Optimierung gehen will...
CStoll schrieb:
Kennst du einen Weg zu fragen, ob ein gegebener Typ einen trivialen Kopierkonstruktor hat?
Suchst du
has_trivial_copy?
-
Nexus schrieb:
CStoll schrieb:
Kennst du einen Weg zu fragen, ob ein gegebener Typ einen trivialen Kopierkonstruktor hat?
Suchst du
has_trivial_copy?
Ja, ich glaube das war's. (wobei ich die Doku so deute, daß das eher pessimistisch bei der Aussage ist - aber für praktische Zwecke dürfte das reichen)
-
CStoll schrieb:
Kennst du einen Weg zu fragen, ob ein gegebener Typ einen trivialen Kopierkonstruktor hat? Wenn ja, könnte man die obengenannten enable_if-Konstrukionen darauf ansetzen.
Nein. Leider hat C++ keine Metaklassen wie Smalltalk sie hat. Ich denke, mit ihnen wäre einiges einfacher.
Ups, wo wir schon dabei sind,
- warum ist der Rückgabetyp eines Kunstuktors nicht void,
- warum ist der Rückgabetyp eines throw-Ausdrucks void, also warum ist es ein Ausdruck?
-
volkard schrieb:
Nein. Leider hat C++ keine Metaklassen wie Smalltalk sie hat.
Ich kenne Smalltalk nicht, wie sehen die aus? Läuft das nicht auf was Ähnliches wie Template-Metaprogrammierung heraus, nur etwas benutzerfreundlicher?
volkard schrieb:
warum ist der Rückgabetyp eines Kunstuktors nicht void
Wahrscheinlich weil der Konstruktor nicht nichts zurückgibt. Schliesslich wird ein Konstruktor in einer Deklaration oder in einem Ausdruck aufgerufen, der das eben konstruierte Objekt zurückgibt. Der Typ eines solchen Ausdrucks ist im Gegensatz zu
void-Funktionen nichtvoid.volkard schrieb:
- warum ist der Rückgabetyp eines throw-Ausdrucks void, also warum ist es ein Ausdruck?
Ich bin mir nicht sicher, könnte mir aber vorstellen, damit man sowas schreiben kann:
boolExpr ? DoSomething() : throw Exception()
-
Quatsch
-
Nexus schrieb:
volkard schrieb:
Nein. Leider hat C++ keine Metaklassen wie Smalltalk sie hat.
Ich kenne Smalltalk nicht, wie sehen die aus? Läuft das nicht auf was Ähnliches wie Template-Metaprogrammierung heraus, nur etwas benutzerfreundlicher?
Nee. Ist die Magie über der Klasse als normale Klasse. Dadurch erst zugreifbar für Metaprogrammierung. In C++ ist es einfach nicht da.
Nexus schrieb:
volkard schrieb:
warum ist der Rückgabetyp eines Kunstuktors nicht void
Wahrscheinlich weil der Konstruktor nicht nichts zurückgibt.
Also falsch.
Nexus schrieb:
volkard schrieb:
- warum ist der Rückgabetyp eines throw-Ausdrucks void, also warum ist es ein Ausdruck?
Ich bin mir nicht sicher, könnte mir aber vorstellen, damit man sowas schreiben kann:
boolExpr ? DoSomething() : throw Exception()Wozu? Nur um im assert werfen zu können? Der Fehler war doch, daß assert ein Ausdruck war. Keinen hat's gejuckt.
-
volkard schrieb:
wo wir schon dabei sind,
Wieso fordert
mainkeinreturn?
EDIT: Oder wieso istargceinintun nicht einunsigned?
-
volkard schrieb:
warum ist der Rückgabetyp eines Kunstuktors nicht void
Im Prinzip ist es irrelevant, welchen Rückgabewert der Konstruktor hat, weil es keine Möglichkeit gibt, ihn direkt aufzurufen.
MyClass a = MyClass(...)ruft ihn nur indirekt auf, sonst müsste esMyClass::MyClass(...)heißen. Der Konstruktor ist aber auch nicht statisch, also ginge das auch nicht. Somit müsste man also danacha.MyClass(...)aufrufen können, das geht nicht.
Da der Konstruktor somit niemals in einem Ausdruck verwendet werden kann, braucht er keinen Rückgabewert.Interessanter wird die Sache beim Destruktor. Der kann in Ausdrücken verwendet werden. Laut http://ideone.com/gn36G scheint er beim GCC auch tatsächlich
voidals Rückgabewert zu haben, ob das der Standard genauso sieht, weiß ich aber nicht.
-
ipsec schrieb:
volkard schrieb:
warum ist der Rückgabetyp eines Kunstuktors nicht void
Im Prinzip ist es irrelevant, welchen Rückgabewert der Konstruktor hat, weil es keine Möglichkeit gibt, ihn direkt aufzurufen.
Schade. Wäre direkter, als der Umweg per placement new.
ipsec schrieb:
MyClass a = MyClass(...)ruft ihn nur indirekt auf, sonst müsste esMyClass::MyClass(...)heißen. Der Konstruktor ist aber auch nicht statisch, also ginge das auch nicht. Somit müsste man also danacha.MyClass(...)aufrufen können, das geht nicht.Eine Aufrufabkürzung darf es ja geben. Warum ist er nicht statisch?
MyClass* p=malloc(sizeof(MyClass)); MyClass::constructor(p);sieht doch hübsch aus. Man könnte zum Beispiel auf natürliche Weise die Adresse der Funktion ziehen.
Da der Konstruktor somit niemals in einem Ausdruck verwendet werden kann, braucht er keinen Rückgabewert.
void als Rückgabewert würde aber auch nicht schaden, sondern den Laden ein wenig vereinfachen. Third-Party-Tools hätten es leichter, den Konstruktor als Funktion zu erkennen. Und schau Dir folgenden seltsamen Code an:
void test(){ //tuwas //if(was) return throw 0;//Klappt, seit der so spät nachträglichen Sprachvereinfachung, daß man void returnen darf. //tuwasanderes } class MyClass{ MyClass(){ //tuwas //if(was) return throw 0;//error: returning a value from a constructor //tuwasanderes } };Da stimmt doch konzeptionell was nicht. Und es ist kein hübscher Weg, durch immer mehr Ausnahmeregeln die Ausnahmen zu regeln und dabei noch mehr Ausnahmen zu provozieren.
Interessanter wird die Sache beim Destruktor. Der kann in Ausdrücken verwendet werden.
Ja, der ist auch (fast) eine ganz normale Methode. Nur wenige Sonderregeln, wie daß er Basisklassendestruktoren automatisch aufruft, den vptr ändert, implementiert werden muß selbst wenn pur virtuell seiend, und nicht überladen werden kann. Kann man wenigstens seine Adresse ziehen?