2

In classA I've got:

static const double alias_var = classB::const_var;

Then in classB:

static const double const_var = 1000.;

But the compiler keeps telling me:

'classB::const_var' cannot appear in a constant-expression.

Why not? The funny thing is if I change classB::const_var from a double to an int, the errors go away.

I inlined these variables for optimization. I hope that using floating-points doesn't prevent the optimization.

I'm using GCC 5.4.0 in a Ubuntu 64-bit environment. I'm sure the fact I'm using Qt4 has nothing to do with it.

Edit: my best workaround is to have in classB:

static const int const_var_int = 1000;
static const double const var = const_var_int;

and then in classA (any everywhere else) assign const_var_int to my floating-points. It gets rid of the errors. I don't know if it's defeating the purpose or what other consequences there are.

Opux
  • 702
  • 1
  • 10
  • 30

1 Answers1

4

Short answer: use constexpr instead of const.

Long answer: there are special provisions in old C++03 which allow class members which are static integral constants be used in constant expressions. This provision does not apply to non-integral (doubles).

With C++11, constexpr removed this limitation.

SergeyA
  • 61,605
  • 5
  • 78
  • 137
  • Looks like I've got a little to learn about these newer C++s. I'm not even sure which one I'm using and I'm getting "warning: identifier 'constexpr' is a keyword in C++11 [-Wc++0x-compat]" – Opux Jan 19 '18 at 16:16
  • 2
    @Opux I sincerely believe that Using C++2003 in 2018 is sin. Would you like to drive 2003 Toyota today? – SergeyA Jan 19 '18 at 16:23
  • I'm sure my 2007 Civic will still be going on strong in 3.5 years. That upgrade would require widespread changes and those decisions aren't up to me. I can mention it to my boss, but in the meantime, what should I do? I've edit my answer w/my best idea for a workaround – Opux Jan 19 '18 at 16:30
  • @Opux If such is the case, just don't use `double` as a constexpr – Passer By Jan 19 '18 at 16:36
  • As long as your workaround works, it works. I am not sure if you are defeating the purpose since I do not know what is your purpose. – SergeyA Jan 19 '18 at 16:37
  • Abstraction and optimization. I think I can answer my own question about abstraction, but these errors make me think that the optimizer won't be able to be as clever w/doubles as it is w/ints. Oh and fwiw, "cerr << "and you are runnign: " << __cplusplus << endl;" reveals "and you are runnign: 199711" – Opux Jan 19 '18 at 16:44
  • 1
    @Opux Since this is non-standard extension of GCC anyways to allow this anyways (as standard doesn't allow for in-class initialization of const doubles). Looks like gcc 5.4 does indeed use in-class set value instead of reading the variable, so your optimization should be there. Beware - it is an error in later versions of GCC. – SergeyA Jan 19 '18 at 16:53
  • So you're saying I've harmed *portability*. Fortunately, I can fix that when the time comes – Opux Jan 19 '18 at 16:55