static constexpr Variable als Parameter an make_shared übergeben
-
Hallo,
ich verwende make_shared wobei ich als Parameter eine static constexpr variable übergeben will. Jedoch gibt der Compiler einen Fehler aus, den ich nicht nachvollziehen kann bzw verstehe warum. Wenn jedoch die static constexpr variable mit datentyp(variable) übergeben wird dann funktioniert es.#include <memory> class Data { public: static constexpr int VAL{0xFF}; }; int main() { auto ok{std::make_shared<int>(int(Data::VAL))}; // This compiles correct auto dontCompile{std::make_shared<int>(Data::VAL)}; // This doesn't compile. Error: undefined reference to `Data::VAL' }
- Warum muss die Variable mit datentyp(variable) übergeben werden?
- Was macht eigentlich datentyp(variable) ? Das ruft ja nur den Konstruktor auf, den es bei elementaren Datentypen gar nicht gibt, oder?
-
Statische Variablen (anscheinend auch
constexpr
) benötigen eine explizite Definition (wenn nicht nur der Wert, sondern eine Referenz oder deren Adresse benötigt werden):constexpr int Data::VAL;
s.a. Ideone-Code
PS: Auch die nativen Datentypen haben (eingebaute) Konstruktoren.
-
Danke für deine Antwort!
Ok also make_shared nimmt die Parameter anscheinend als Referenz entgegen.
Was mich aber trotzdem verwirrt ist, dass ein Literal als Parameter zulässig istauto ok1{std::make_shared<int>(0)}; // This compiles correct
und der Compiler eigentlich den static consexpr Wert auch direkt als Literal einsetzen müsste.
-
@th69 sagte in static constexpr Variable als Parameter an make_shared übergeben:
Statische Variablen (anscheinend auch constexpr) benötigen eine explizite Definition
Das hat sich mit C++ 17 geändert.
https://en.cppreference.com/w/cpp/language/staticIf a static data member is declared constexpr, it is implicitly inline and does not need to be redeclared at namespace scope. This redeclaration without an initializer (formerly required as shown above) is still permitted, but is deprecated. (since C++17)
-
@godi sagte in static constexpr Variable als Parameter an make_shared übergeben:
und der Compiler eigentlich den static consexpr Wert auch direkt als Literal einsetzen müsste
Warum?
-
@godi sagte in static constexpr Variable als Parameter an make_shared übergeben:
Ok also make_shared nimmt die Parameter anscheinend als Referenz entgegen.
Was mich aber trotzdem verwirrt ist, dass ein Literal als Parameter zulässig istauto ok1{std::make_shared<int>(0)}; // This compiles correct
und der Compiler eigentlich den static consexpr Wert auch direkt als Literal einsetzen müsste.
s. make_shared
Es sind ja "rvalue" references (also
&&
), und damit kann man auch Werte (Literale) übergeben.
-
@th69 sagte in static constexpr Variable als Parameter an make_shared übergeben:
Es sind ja "rvalue" references (also &&), und damit kann man auch Werte (Literale) übergeben.
Nein.
Erstmal sind es keine rvalue-references sondern universal-references. Und dann kann man Literale auch wunderbar übergeben wenn der ParametertypT const&
ist. Das ging sogar schon in C++98.
-
Ich halte mich eher an "Universal References" in C++11. Außerdem taucht dieser Begriff auch nicht im Link references auf.
Und ich hatte mich auf folgendes bezogen:
@godi sagte in static constexpr Variable als Parameter an make_shared übergeben:
Ok also make_shared nimmt die Parameter anscheinend als Referenz entgegen.
Was mich aber trotzdem verwirrt ist, dass ein Literal als Parameter zulässig istUnd bei einer normalen Referenz (ohne const) kann man eben keine Literale übergeben.
-
Referenzen "ohne const" sind alles andere als normal.
-
Sprachtechnisch schon, sonst würde man ja nicht extra "const" davorsetzen müssen.
Dass man in in den meisten Programmteilen eher "const"-Referenzen benutzt, ist ja eher ein Idiom (damit man nicht automatisch Schreibrechte hat).