简体   繁体   中英

c++ static template subclasses

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.

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.
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM