#include <iostream>
class IBase
{
public:
virtual ~IBase() = default;
//a static member identifying IBase (e.g. "iid.base")
static const char* const IID; //initialize in implementation file
//[...]
};//class IBase
class IDerived : public IBase
{
public:
virtual ~IDerived() = default;
//a static member identifying IDerived (e.g. "iid.derived")
static const char* const IID; //initialize in implementation file
//[...]
};//class IDerived
class IEvenMoreDerived : public IDerived
{
public:
virtual ~IEvenMoreDerived() = default;
//missing static const member IID!
//[...]
};//class IEvenMoreDerived
const char* const IBase::IID = "IBase";
const char* const IDerived::IID = "IDerived";
template <typename T>
struct IdName
{
static const char* const IID;
};
template <> const char* const IdName<IBase>::IID = "IBase";
template <> const char* const IdName<IDerived>::IID = "IDerived";
template<typename T>
void queryIID()
{
std::cout << T::IID << std::endl; // IEvenMoreDerived::IID is resolved as IDerived::IID
std::cout << IdName<T>::IID << std::endl; // link error for IEvenMoreDerived::IID.
}
int main()
{
queryIID<IBase>();
queryIID<IDerived>();
queryIID<IEvenMoreDerived>();
}