Reputation: 2832
I have read about why static virtual
methods don't make any sense - either the function is virtual
so it can be overridden by an implementation, or it's static
because the type is known at compile-time, and it can't be both. I'm wondering if there's a way to do what I'm trying:
I have the same basic structure for reading in some pre-configured values:
// in some header
template < typename TYPE >
class Reader {
public:
static TYPE getValue() {
static TYPE value;
static SomeFileClass(filename, &value, sizeof(value));
return value;
}
};
class OneValue : public Reader<uint16_t> {
public:
static const char* filename;
};
// and maybe OtherValue : public Reader<SomeUserType> {}; etc etc.
// in main.cpp, for example
const char* OneValue::filename = "onevalue.txt";
This, and various variations of this, fail. First it said filename
wasn't declared in Reader
which sounds reasonable; so then I declared a static const char* filename
there, with the plan of intentionally shadowing Reader::filename
with OneValue::filename
, because when I use it later on, I will call OneValue::getValue()
- I know the type when I'm calling it.
However, that doesn't work because Reader::filename
isn't defined, but when I define it, it says template used without template parameters` which also sounds like a reasonable error, but now I'm out of ideas.
Is there a way to cleanly do what I want, without a lot of code copying? I'm open to completely new formulations, just want it to be clear and concise - the code above, while it has contrived names, is actually the entirety of the Reader
class I was hoping to implement, so re-defining some getValue()
in each derived class is more work than desired, since it would take probably more lines to derive-and-override than to just reimplement getValue()
for each class.
Upvotes: 1
Views: 121
Reputation: 157344
The usual solution to this kind of problem is CRTP:
template < typename TYPE, typename Derived >
// ^^^^^^^^^^^^^^^^^^
class Reader {
public:
static TYPE getValue() {
static TYPE value;
static SomeFileClass(Derived::filename, &value, sizeof(value));
// ^^^^^^^^^
return value;
}
};
class OneValue : public Reader<uint16_t, OneValue> {
// ^^^^^^^^^^
// etc.
};
Upvotes: 4