How to define compilation constant (static) inside a C ++ class?

I have some constants that need to be used only at compile time to simplify the code, so I don't need the actual variables available at runtime.

Traditionally, this was done with #define NAME 123 , but I would like to use type safe.

Outside of classes, you can const int name = 123; which works fine, but it doesn't seem possible to put it inside a class. For instance:

 class Example { public: const double usPerSec = 1000000.0; }; double usOneMinute = 60 * Tempo::usPerSec; 

Works with Visual C ++, but does not work with GCC:

 error: non-static const member 'const double Example::usPerSec', can't use default assignment operator 

You can fix this by making it static, but then Visual C ++ complains:

 error C2864: 'Example::usPerSec' : a static data member with an in-class initializer must have non-volatile const integral type type is 'const double' 

I assume that VC ++ will only accept static const int .

I want to avoid setting the value in the constructor, because then I need an instance of the class at runtime to access the value, while in fact I want all this to be processed at compile time, for example with #define .

So, how can I define a constant as double inside a class without resorting to its global use or using #define , which will work without an instance of the class and work with the main C + +03 compilers?

+5
source share
5 answers

There is a difference between integral and other types. For integral types, you can always define them as const static , as in

 struct Example { const static int name = 123; // added 'static' to code in text of question const static unsigned usPerSec = 1000000; }; 

For non-integer types, for example double in your example, the situation is more complicated. Since 2011 (using the compiler option std=c++11 with most compilers) you can simply do this:

 struct Example { constexpr static double usPerSec = 1000000.0; }; 

But with gcc this

 struct Example { const static double usPerSec = 1000000.0; }; 

should work in C ++ 03 (this is a GNU extension).

However, the standard approach in C ++ 03, which is also used by the standard library itself (for example, in std::numeric_limits<> ), is a static member function

 struct Example { static double usPerSec() { return 1000000.0; } }; 
+10
source

I see two possible approaches to C ++ 03:

  • Use a static member function and rely on inlining:

     class Example { public: static double usPerSec() { return 1000000.0; } }; double usOneMinute = 60 * Example::usPerSec(); 
  • Use a static data member and go into constant bending mode (a value using a constant will be computed at runtime):

     class Example { public: static const double usPerSec; }; double usOneMinute = 60 * Example::usPerSec; // Somewhere in one .cpp const double Example::usPerSec = 1000000.0; 
+4
source

If I were you, I would put it in a namespace:

 namespace MyExampleNamespace { const double usPerSec = 1000000.0; } double usOneMinute = 60 * MyExampleNamespace::usPerSec; 
+2
source

This code works with both vC ++ and gcc:

 class Example { public: static const double usPerSec ; }; const double Example::usPerSec=10000.0; double usOneMinute = 60 * Example::usPerSec; 
+1
source

You have to make it static const and then give it a value outside the class. Do not do this inside the constructor. You do not need to do make instance

 class Example { public: static const double usPerSec; 

};

 double Example::usPerSec = 1000000.0; 

Now you can use it anywhere without any class instances

 double someVar = Example::usPerSec; 
+1
source

Source: https://habr.com/ru/post/1211232/


All Articles