2012-05-02 4 views
5

Gibt es eine Möglichkeit, Zeichenfolgen zu implementieren, um sowohl zur Kompilierungszeit als auch zur Laufzeit zu arbeiten?C++ 11 conetexpr Zeichenfolgenimplementierung

AFAIK für eine Klasse, die consExpr konstruiert werden soll, muss sie einen trivialen Destruktor haben. Dies erweist sich jedoch als schwierig, wenn es sich um Strings handelt. Wenn die Zeichenfolge NICHT conexpr ist, muss sie Speicher freigeben. Wenn es jedoch consExpr ist, dann wird es statisch zugewiesen und sollte nicht gelöscht werden, was einen trivialen Destruktor erlaubt.

Es ist jedoch nicht möglich zu sagen "Hey, Compiler! Wenn ich Constexpr bin, müssen Sie mich nicht zerstören!" Oder ist es?

Es wäre so etwas wie die folgenden:

class string { 
private: 
    char * str; 
public: 
    template<std::size_t l> 
    constexpr string(const char (&s)[l]) : str(&(s[0])) {} 
    string(const char * s) { str = strdup(s); } 
    static if (object_is_constexpr) { 
     ~string() = default; 
    } 
    else { 
     ~string() { free(str); } 
    } 
}; 

Der nächstgelegene ich habe in der Lage zu kommen, ist für zwei unterschiedliche Arten mit, Schnur und constexpr_string, eine benutzerdefinierte wörtliche _string Rückkehr constexpr_string und ein Benutzer implizite Konvertierung von consExpr_string in String.

Das ist nicht sehr schön, aber const auto s = "asdf"_string; funktioniert, aber const string s = "asdf"_string; nicht. Außerdem wird ein Verweis/Zeiger auf einen consExpr_string nicht konvertiert. Die Vererbung führt in beiden Fällen zu nicht intuitiven "Gotchas" und löst das erste Problem nicht.

Es scheint so, als ob es möglich sein sollte, solange der Compiler dem Programmierer VERTRAUEN sollte, dass der constexpr nicht zerstört werden musste.

Wenn ich ein Missverständnis habe, lass es mich wissen.

+0

Ich denke, Sie suchen nach 'strwrap' von http://akrzemi1.wordpress.com/2011/05/11/parsing-strings-at-compile-time-part-i/ – Cubbi

+0

String Literals' const char (& Var) [N] '_are_ der Zeichenfolgetyp 'constexpr'. –

+1

Sie müssen lieben, wenn Leute anfangen, Eigenschaften wie 'statisches if' zu verwenden, bevor sie genehmigt werden! –

Antwort

9

Es ist nicht nur eine Frage der Zerstörung.

A constexpr Betrieb sollte nur rufen andere constexpr Operationen und new, malloc etc ... sind nichtconstexpr. Beachten Sie, dass dies eine statisch überprüfte Eigenschaft ist und nicht vom Laufzeitargument abhängt. Daher muss der Aufruf einer solchen Funktion nicht vorhanden sein und nicht nur in einer Verzweigung verborgen sein, die (vermutlich) nicht verwendet wird.

Als solche wird es nie möglich sein, eine constexprstring zu erhalten.

+0

Es kann nicht einmal in einem Nicht-Constexpr-Konstruktor sein?Es scheint, dass es möglich sein sollte, sowohl constexpr als auch non-consxpr Konstruktoren für einen gegebenen Typ zu haben, genauso wie es möglich ist, const und non-const Methoden zu haben. –

+0

Sie können einen 'constexpr'-String-Typ erstellen, er wird nicht in der Lage sein, Non-Constexpr-Strings zu verarbeiten. Machen Sie einfach Konvertierungsfunktionen. –

+0

Wie ich es sehe, ist constexpr eine Möglichkeit, die Grenze zwischen Kompilierzeit und Laufzeit zu verwischen. Primitive Typen erlauben dies, und es scheint, als ob es möglich sein sollte, einige Dinge zu tun, um Zeigern in Klassen zu erlauben, entweder auf einen literalen oder dynamisch zugewiesenen Speicher zu zeigen. Funktionale Sprachen haben seit einiger Zeit über die Kompilierzeit/Laufzeitgrenze abstrahiert. @Mooing Duck: Konvertierungsfunktionen scheinen die Abstraktion zu unterbrechen –

0

Es ist bis zu einem gewissen Grad möglich, the code example in this page zu sehen. Sie können constexpr conststr Objekte erstellen und einige Operationen für sie aufrufen, aber Sie können sie nicht als nicht typisierte Vorlagenparameter verwenden.