-2

I'm having a strange issue where I'm unable to modify one of the static members of a class after initializing the class. Here's the code I have:

my_values.hpp

#include "weird_class.hpp"
namespace foo {
class Bar {
 public:
  static WeirdClass weird_class_obj;
};

my_values.cpp

#include "weird_class.hpp"
#include "my_values.hpp"
namespace foo {
  WeirdClass Bar::weird_class_obj = WeirdClass(1.0f, 0.0f, 1.0f, 100.0f);
  Bar::weird_class_obj.set_weird_value(100.0f);
}

weird_class.hpp

#ifndef WEIRD_CLASS_H
#define WEIRD_CLASS_H
class WeirdClass {
public:
 WeirdClass(float, float, float, float);
 void set_weird_value(float);
private:
 float weird_value;
};
#endif

weird_class.cpp

#include "weird_class.hpp"
void WeirdClass::set_weird_value(float weirdValue) {
  weird_value = weirdValue;    
}

If I comment out line 5 in my_values.cpp the files compile fine. But if I don't, the error I get is

error: no type named 'weird_class_obj' in 'foo::Bar' Bar::weird_class_obj.set_weird_value(100.0f);
                                                          ^
error: cannot use dot operator on a type Bar::weird_class_obj.set_weird_value(100.0f);
                                                             ^

My guess is that weird_class_obj is somehow being treated as a type rather than an object of class WeirdClass. But why would this be?

user3059347
  • 529
  • 1
  • 9
  • 15
  • 3
    You cannot call member functions out of a namespace scope. Why do you need to reset it anyways? Just initialize it properly inside the constructor. – Jodocus Nov 09 '17 at 11:18
  • 3
    Possible duplicate of [Why statements cannot appear at namespace scope?](https://stackoverflow.com/questions/8470065/why-statements-cannot-appear-at-namespace-scope) – underscore_d Nov 09 '17 at 11:18
  • @Jodocus thanks. This example is a stripped-down version of my actual code, where WeirdClass is actually a PID controller library (that I didn't write, and ideally I shouldn't modify) and weirdValue is an additional configuration parameter that I have to set separately from the constructor. I do have another place to do all that configuration in, though, so things should work out. Thanks for alerting me to the namespace problem. – user3059347 Nov 09 '17 at 14:05

1 Answers1

4

The problem is not that you may not modify the object. The problem is you placed this:

Bar::weird_class_obj.set_weird_value(100.0f);

An executable statement, into namespace scope. That's just not allowed.

If the c'tor of WeirdClass is that weird that you may not set the value in it, but the class is not so weird as to disallow copying/moving, you can use the following trick:

WeirdClass Bar::weird_class_obj = []() {
  WeirdClass obj(1.0f, 0.0f, 1.0f, 100.0f);
  obj.set_weird_value(100.0f);
  return obj;
}();

The above is known in the JavaScript world as an IIFE. If you can't do that for whatever reason, then a named free function can be used for the same purpose as well.

StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458