I'm trying to static instantiate some objects at compile time. What I need is to set to a member int variable an incremented value. For example, the first object I create will have the 0 value, the second 1, the third 2... Summarizing I need something like this but it has to work as constexpr.
//header
class MyClass final {
private:
static int IDcount;
public:
const int ID;
constexpr MyClass(args);
//~MyClass();
};
//source
int MyClass::IDcount = 0;
constexpr MyClass::MyClass(args) : ID(MyClass::IDcount++) {
}
Is there a way to achieve this at compile time (without taking the ID as argument of the constructor)
It can't be done the way you've defined it, but there is a non-standard but widely implemented preprocessor trick that could be employed.
#include <iostream>
struct MyClass final {
constexpr MyClass(int myid, const char *myname)
: id(myid), name(myname) {}
int id;
const char *name;
};
constexpr MyClass m[]{
MyClass(__COUNTER__, "Larry"),
MyClass(__COUNTER__, "Moe"),
MyClass(__COUNTER__, "Curly")
};
int main()
{
for (auto const &obj : m)
std::cout << obj.id << '\t' << obj.name << "\n";
}
The __COUNTER__
macro is defined in Microsoft's Visual C++, gcc since version 4.3 and clang.
When run, this program produces:
0 Larry
1 Moe
2 Curly
A constexpr
-function or ctor must be a valid core constant expression on at least one path:
7.1.5 The constexpr specifier
[dcl.constexpr]
5 For a non-template, non-defaulted
constexpr
function or a non-template, non-defaulted, non-inheritingconstexpr
constructor, if no argument values exist such that an invocation of the function or constructor could be an evaluated subexpression of a core constant expression (5.19), the program is ill-formed; no diagnostic required.
Which means it cannot modify a global object on all paths:
5.19 Constant expressions
[expr.const]
A conditional-expression
e
is a core constant expression unless the evaluation ofe
, following the rules of the abstract machine (1.9), would evaluate one of the following expressions:
- modification of an object (5.17, 5.2.6, 5.3.2) unless it is applied to a non-volatile lvalue of literal type that refers to a non-volatile object whose lifetime began within the evaluation of
e
;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With