Is it possible to enforce, at compile time, that the following is acceptable:
class B {
public:
virtual constexpr const char* getKeyStr() const = 0;
};
class D1 : public B {
public:
constexpr const char* getKeyStr() const override { return "D1"; }
};
class D2 : public B {
public:
constexpr const char* getKeyStr() const override { return "D2"; }
};
... But the following is not? We don't want D1
and D2
to return the same key string:
class B {
public:
virtual constexpr const char* getKeyStr() const = 0;
};
class D1 : public B {
public:
constexpr const char* getKeyStr() const override { return "D1"; }
};
class D2 : public B {
public:
constexpr const char* getKeyStr() const override { return "D1"; } // can we error out here at compile time?
};
Clarifications:
I am only showing two derived classes in this example, but what I am trying to achieve is to post this constraint on any number of derived classes.
The underlying problem to solve: I am thinking about a serializing/deserializing application, where each object with the same base class will be able to generate a textual/string representation of itself to be written to a file and, when given that string back (let's call it the content-string), will be able to reconstruct the corresponding data.
During deserialization, the application code should be able to tell from a key part of the content-string, let's call it the key-string, what derived object should be reconstructed. Therefore, the key-string needs to be unique for each derived class. I know type_info::name
could be unique, but it is not customizable (or compiler independent?).
Regarding the getKeyStr()
function (corresponding to the key-string mentioned above), it should always return the same string for all objects of the same derived class.
If you can have a list of all Derived classes, you might do something like:
template <typename... Ts>
bool have_unique_keys()
{
std::string_view keys[] = {Ts{}.getKeyStr()...}; // requires constexpr default constructor
// static method might be more appropriate
std::sort(std::begin(keys), std::end(keys)); // constexpr in C++20
auto it = std::adjacent_find(std::begin(keys), std::end(keys));
return it != std::end(keys);
}
static_assert(have_unique_keys<>(D1, D2, D3));