2016-04-07 3 views
3

Ich verstehe, dass constexpr Ihnen erlauben würde, ein Objekt als eine Konstante zum Zeitpunkt der Kompilierung zu verwenden, aber was ist ein Beispiel dafür, wann dies von Vorteil wäre? Ich versuche, das Schlüsselwort besser zu verstehen, aber ich kann kein gutes Beispiel finden, das übergeht, wenn ich es für einen Konstruktor verwende, der erklärt, warum es benötigt wird.Warum würden Sie einen Contexpr auf einem Konstruktor verwenden?

Die beiden folgenden Beispiele funktionieren, also warum wird der consExpr auf den Konstruktor gelegt?

Mit constexpr auf Konstruktor:

#include <iostream> 
using namespace std; 

class Rect 
{ 
    public: 
     constexpr Rect(int width, int height) 
      : mWidth(width), mHeight(height) {} 
     constexpr int getArea() const { return mWidth * mHeight; } 
    private: 
     int mWidth, mHeight; 
}; 

int main(int argc, char* argv[]) 
{ 
    constexpr Rect r(8, 2); 

    cout << r.getArea() << endl; //16 

    int myArray[r.getArea()]; // OK 


    return 0; 
} 

Ohne constexpr auf Konstruktor:

#include <iostream> 
using namespace std; 

class Rect 
{ 
    public: 
     Rect(int width, int height) 
      : mWidth(width), mHeight(height) {} 
     constexpr int getArea() const { return mWidth * mHeight; } 
    private: 
     int mWidth, mHeight; 
}; 

int main(int argc, char* argv[]) 
{ 
    Rect r(8, 2); 

    cout << r.getArea() << endl; //16 

    int myArray[r.getArea()]; // OK 


    return 0; 
} 
+1

Zweite kompiliert nicht für mich: http://coliru.stacked-crooked.com/a/a84bbdd8fb82bb49 – Brian

+0

Aber consExpr ist in beiden Beispielen für 'getArea()' platziert. –

+1

Eine mit 'constexpr' gekennzeichnete Funktion gibt nur dann einen konstanten Ausdruck zurück, wenn ihre Argumente (einschließlich implizierter '* this') ebenfalls konstante Ausdrücke sind. –

Antwort

6

In Ihrem zweiten Beispiel wird int myArray[r.getArea()]; nicht in Standard C++ erlaubt, da r.getArea() keine Konstante ist Ausdruck. (Wenn Ihr Compiler dies akzeptiert, dann verlassen Sie sich auf eine Compiler-Erweiterung und sollten eine Warnung ausgeben, wenn Sie den Compiler im konformen Modus aufrufen).

Der Unterschied könnte offensichtlicher sein, wenn Sie das Array ändern:

std::array<int, r.getArea()> myArray; 

, die es unwahrscheinlich ist, dass der Compiler in der nicht constexpr Version zu akzeptieren.

+0

Nun, das tut es wirklich nicht Beantworten Sie meine Frage, aber was Sie im Grunde sagen, ist, dass Sie "constexpr" nur für einen Konstruktor verwenden würden, der ein Objekt erzeugen würde, das zur Kompilierungszeit als Literal verwendet werden müsste? –

+0

@EavenSheets Sie haben gefragt: "Die beiden folgenden Beispiele funktionieren, also warum wird der consExpr auf den Konstruktor gelegt?" . Ich habe das angesprochen, indem ich gezeigt habe, dass das zweite Beispiel tatsächlich nicht funktioniert und die Platzierung von "constexpr" auf dem Konstruktor es funktioniert. "Warum würden Sie einen Konstrukteur für einen Konstrukteur benutzen?" wird beantwortet mit "Wenn Sie möchten, dass Objekte dieser Klasse zum Erzeugen eines konstanten Ausdrucks verwendet werden können". –

+0

Dies beantwortet die Frage nicht. –