2011-01-06 14 views
3

Ich habe eine Template-Klasse, die von zwei Template-Parametern abhängig ist, um ihre Werte zu berechnen, aber nur eine für die Konstruktion. Ich möchte die Abhängigkeit von der Sekunde während seiner Lebenszeit entlasten. Ich schaue mir das an, indem ich eine statische Template-Funktion verwende, um die Werte zu berechnen und dann eine Instanz zu erstellen. Alle Mitglieder in dieser Klasse sind const POD-Typen und es wird ein Großteil dieser Klasse beim Start der Anwendung erstellt werden.statische Konst-Referenzen zu Provisorien

template < class member > 
class FOO { 
public: 
FOO() : a(7) {}; 

template < class scope > 
static FOO CreateFOO() 
{ 
    return FOO(); 
}; 

private: 
const int a; 
}; 

template < class member, class scope > 
const FOO<member>* function() 
{ 
static const FOO<member>& temp = FOO<member>::CreateFOO<scope>(); 

return &temp; 
} 

int main() { 

const FOO<int>* b = function< int, int >(); 

return 0; 
} 

Ich betrachtete Bewegung Semantik, sondern weil ich einfach const POD-Typen gibt es wirklich enthalten bin, ist nicht Swapping und Bewegen einfach kopieren und zu zerstören. Ist das oben genannte angemessen/gültig? Alles, was ich gelesen habe, deutet darauf hin, dass es in Ordnung ist! Gibt es einen besseren Weg, dies zu tun?

+3

Ich habe keine Gründe sehen für die Verwendung von 'static const Type &' statt 'static Const Typ '. Was denkst du, dass es dich gewinnt? –

+0

Ich kann an einen rvalue binden? ohne zu kopieren? –

+0

Ein Compiler sollte das Kopieren optimieren, wenn Sie das neue Objekt nach Wert zurückgeben, aber dafür gibt es keine Garantie. Ich wünschte, es wäre vorhersehbar, wann das Kopieren stattfindet und wann nicht. – Kos

Antwort

2

Das sollte in Ordnung sein. Da die Referenz temp an das temporäre Objekt gebunden ist, verlängert sich die Lebensdauer des temporären Objekts auf die Lebensdauer von temp, die über das Ende von main() hinausgeht.

Aber ich sehe keinen wirklichen Grund, eine Referenz dort zu verwenden. Warum nicht einfach:

{ 
    static const FOO<member> foo = FOO<member>::CreateFOO<scope>(); 
    return &foo; 
} 

Ihr Compiler kann wahrscheinlich den Kopierkonstruktor optimieren. Und wenn nicht, sagst du, es sind alles POD-Mitglieder, also keine große Sache.

In beiden Fällen können Sie sich über die static deinitialization order fiasco sorgen. Oder vielleicht bist du sicher, dass sie niemals von Destruktoren benutzt werden.

0

Ich verstehe, dass es ein künstliches Beispiel ist. Dennoch gibt es keinen Grund für die Existenz von static FOO CreateFOO(), die in diesem Fall nichts anderes als das Standard-Konstruieren des Objekts tut. Wenn Sie einfach eine Vorlage Konstruktor erstellt:

template < class member > 
class FOO { 
public: 
template < class scope > FOO(scope); 

dann würden Sie ein Standardformular für Ihre Singletons haben:

template < class member, class scope > 
const FOO<member>& function(scope your_scope) 
{ 
static FOO<member> temp(your_scope); 
return temp; 
} 
+0

Ich bin nicht auf der Suche nach einem Singleton, FOO wird im Kontext des Umfangs erstellt, aber die Abhängigkeit vom Geltungsbereich ist nur für die Dauer der Konstruktion. Ich kann viele FOO s alle mit verschiedenen const Werten haben. Die statischen Initialisiererfunktionen sind im Geltungsbereich, FOO < member > wird jedoch außerhalb des Bereichs aufgerufen. Es kann auch viele FOO s im Umfang geben. Ich hoffe das macht Sinn :/ –

Verwandte Themen