11

Inside the header file of my class, I am trying the following and getting compiler complaints:

private:
    static const double some_double= 1.0;

How are you supposed to actually do this?

curiousguy
  • 8,038
  • 2
  • 40
  • 58
zebra
  • 6,373
  • 20
  • 58
  • 67
  • I think you can't put that in the header file. It would break the rule about defining constants only once. According to this andser on SO: http://stackoverflow.com/questions/2777541/static-const-double-in-c – Ziggy Dec 09 '11 at 02:11
  • ¤ If you want to do it entirely in the header (as the question indicates), then there are two main ways. The first and easiest is to define an inline function that produces the value, or a reference to the value. The second is to use the **templated constant trick**, as illustrated [in this linked-to example](http://codepad.org/ycUPIxNy). I think of the templated constant trick as mine, since with one exception that occurred some years ago, I'm the only one I know who has advocated and/or discussed it. However, if you don't like either solution, then just compile separately. Cheers & hth., – Cheers and hth. - Alf Dec 09 '11 at 02:18
  • Amendment: I didn't know that C++11 `constexpr` could be used in the way illustrated in KerrekSB's answer, so that's now a third way. :-) – Cheers and hth. - Alf Dec 09 '11 at 02:28
  • @Cheersandhth.-Alf `constexpr` doesn't seem to help if you want to have a reference of the static member (which might be necessary when passing to function which takes param as const ref) -- However, if you want `constexpr` and keep it in header and be able to ref it, I guess your dummy template trick (which, if I understood it correctly, is just a way to work around ODR) simply with an added `constexpr` should do it... – leemes Jul 02 '14 at 00:55
  • (like here: http://ideone.com/Q4JU5R) – leemes Jul 02 '14 at 01:02

3 Answers3

21

In C++11, you can have non-integral constant expressions thanks to constexpr:

private:
    static constexpr double some_double = 1.0;
Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • 3
    This is more than just confusing! What `constexpr` does that `const` couldn't do? If `constexpr` is allowed, why wouldn't `const` imply `constexpr`? It seams that C++ breaks its own historical design. – curiousguy Dec 09 '11 at 04:16
  • 3
    `const` does not imply `constexpr`. `constexpr` implies `const`. `constexpr` is stricter than `const`. Consider `const auto seed = clock();`, `seed` is a constant variable (its value will not be able to be changed later), but it is not a constant expression (it could not be used to size an array if it were itegral). `constexpr` is designed to express a distinction between compile-time and run-time determination, where `const` is more of an interface and/or access privilege specifier. – John Apr 23 '14 at 21:51
  • @John: That's roughly true, but it's more subtle than that: `constexpr` member functions shouldn't automatically be `const`, but this only gets fixed in C++14. – Kerrek SB Apr 23 '14 at 21:52
  • 1
    This doesn't necessarily work, see: http://stackoverflow.com/questions/8452952/c-linker-error-with-class-static-constexpr – Eloff Feb 04 '16 at 03:29
  • @Eloff: That's not a contradiction. If you odr-use the variable, you have to define it, but that doesn't stop you from having a constant expression. – Kerrek SB Feb 04 '16 at 10:26
4

Declare it in the header, and initialize it in one compilation unit (the .cpp for the class is sensible).

//my_class.hpp
private:
static const double some_double;

//my_class.cpp
const double my_class::some_double = 1.0;
twsaef
  • 2,082
  • 1
  • 15
  • 27
3

I've worked around this issue by doing this:

//my_class.hpp
const double my_double() const {return 0.12345;}

//in use
double some_double = my_class::my_double();

I got the idea from

math::pi()
covstat
  • 331
  • 1
  • 3
  • 10