Wie man den default-Wert eines beliebigen Typs
In C# kann ich etwas schreiben wie dieses:
class AnyThing<T>
{
static public T Default = default(T);
}
static void Main ()
{
int i = AnyThing<int>.Default;
Console.WriteLine (i==0);
string s = AnyThing<string>.Default;
Console.WriteLine (s == null);
}
Ich beabsichtige zu schreiben, ein Wörterbuch wie die Vorlage-Klasse in C++, ich würde gerne die dict-die Rückkehr der default-Wert (null) von der generischen TVal geben, wenn der angegebene Schlüssel nicht gefunden werden. In C# die Standard - (T) konstruieren Sie kommt zu retten, während in C++ bin ich mir nicht sicher, was ist der geeignete Weg, um das gleiche zu tun.
Ich habe versucht T obj = {}
und T* obj = {}
mit gcc4.7, funktioniert es auch. Ich bin nur nicht so sicher, ob es die syntax definiert die Sprachspezifikation, wenn diese irgendwie wird der code tragbare-cross-Compiler und Plattformen. Bitte helfen Sie mir mit meinem doudt! Vielen Dank im Voraus!
PS:
~~~~~~~~~~
Sicherstellen, dass die Vorlage erhalten Sie den Standardwert(null) Wert eines BELIEBIGEN Typs, auch von denen, die nicht aufrufbar default ctor, verwendete ich folgenden Mechanismus (inspiriert durch avakar Antwort):
template<class T>
struct AnyThing
{
static const T& Default ;
private:
static const char temp[sizeof(T)];
};
template<class T> const char AnyThing<T>::temp[] = {};
template<class T> const T& AnyThing<T>::Default = *(T*)temp;
struct st
{
double data;
st()=delete;
};
int main()
{
cout << (int)AnyThing<char*>::Default<<endl; //0
cout << AnyThing<int>::Default<<endl; //0
cout <<AnyThing<st>::Default.data<<endl; //0
}
Sieht es hässlich aus, aber sollte nicht dazu führen, keine Probleme, alle gelöscht Objekt ist nur ein Stück leere Speicher. Bin ich falsch?
- stackoverflow.com/questions/1962600/...
- Ich bin nicht ganz sicher, ob dies Ihr problem löst, aber ich denke, Boost.Wert Initialisiert versucht, zur Adresse dieses problem.
Du musst angemeldet sein, um einen Kommentar abzugeben.
In C++ gibt es sowas wie
default
- Schlüsselwort in C#. Da die Initialisierung von default-Konstruktor von Wert-Klasse-Typ gescheitert, wenn default-Konstruktor istprivate
. In C#, wenn default-Konstruktor ist private, Wert-Klasse-Typ wird initialisiertnull
seit Klasse-Typ istreference-type
.Initialition von
{}
ist definiert durch language-Spezifikation. Es ist C++11. In C++03, die Sie verwenden solltenAls zeigte durch bames53 im Kommentar, wenn Sie möchten, initialisieren
T*
Sie verwenden sollten,vor C++11.
oder
in C++11.
oder
double* obj = double()
funktioniert nicht.T t = T();
auch funktioniert, wenn T ein Zeiger-Typ.int i = int();
müssen Sie nichtAnything<T>
.int i = default(int);
ist korrekt (überprüft in C# 4.0).T *t = T*();
eigentlich nicht arbeiten. Da der default-Wert für alle Zeiger der null-Zeiger, die Sie verwenden konntenT *t = NULL;
. Wenn Sie eine C++11-compiler, sollte man einfach vorziehen, uniform initialization syntaxT *t = {};
oderT *t{};
.T
muss kopierbar hier. Es gibt einen Weg, dies zu tun, ohne die Notwendigkeit für den Kopier-Konstruktor, siehe meine Antwort.Genommen buchstäblich aus "The C++ Programming Language, Third Edition von Bjarne Stroustrup":
BEGINNEN ZITAT
4.9.5 Initialisierung [dcl.init]
Wenn eine Initialisierung angegeben ist, für ein Objekt, dass die Initialisierung bestimmt der erste Wert eines Objekts. Wenn keine Initialisierung angegeben ist, wird eine Globale (§4.9.4), namespace (§8.2), oder lokale statische Objekt (§7.1.2, Ziffer 10.2.4) (zusammenfassend als statische Objekte) mit 0 initialisiert wird, der den entsprechenden Typ. Zum Beispiel:
Lokale Variablen (manchmal auch automatische Objekte) und Objekte auf dem free store (manchmal auch als dynamische Objekte oder heap-Objekte) nicht initialisiert werden standardmäßig. Zum Beispiel:
Mitglieder von arrays und Strukturen werden default-initialisiert oder nicht, je nachdem, ob das array oder Struktur ist statisch. Benutzerdefinierte Typen können default-Initialisierung definiert (§10.4.2).
Komplizierter Objekte erfordern mehr als einen Wert als eine Initialisierung. Dies erfolgt durch die Initialisierer-Listen getrennt durch { und } für C-style-Initialisierung von arrays (§5.2.1) und Strukturen (§5.7).
Für Benutzer-definierte Typen mit Konstruktoren, Funktion-style-argument-Listen verwendet werden (§2.5.2, §10.2.3). Beachten Sie, dass ein leeres paar von Runden Klammern () in einer Erklärung heißt immer "Funktion" (§7.1). Zum Beispiel:
ZITAT ENDE
So, können Sie den default-Wert eines beliebigen Typs bilden ein statisches Objekt von diesem Typ:
T()
Lösung nicht mehr funktioniert, wenn ich Sie gelöscht, der Fehler ctor von T, oder erklärt es als privat, aber in C#default(T)
funktioniert trotzdem, damit es nicht buchstäblich für JEDEN Typ! Was für ein setback1Immer die Antwort wird nicht funktionieren, wenn
T
keine Kopie-Konstruktor. In C++03 gibt es keine Möglichkeit, null-initialisieren Sie eine variable, die sowohl Allgemeine als auch elegant. Was bleibt, ist der folgende trick.Hier
temp[0]
ist null initialisiert und dann anobj
. No copy-Konstruktoren benötigt werden.Erstellen Sie Ihre eigenen Standard-Schlagwort:
Verwenden Sie es wie:
Oder mit einer leichten semantischen variation: