Assuming the following class hierarchy:
//file base.h
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
Every class in this hierarchy must have its own static const tChar* const iid
which can be used to identify the object without instantiating it. In IEvenMoreDerived
this information is missing.
Now, somewhere in the code, I have a function template where the IID is accessed:
//file main.cpp
#include "base.h"
template<typename T>
void queryIID()
{
std::cout << T::IID << std::endl;
}
int main(int argc, char* argv[])
{
queryIID<IBase>(); //prints "iid.base"
queryIID<IDerived>(); //prints "iid.derived"
queryIID<IEvenMoreDerived>(); //probably prints "iid.derived"
return 0;
}
My intention is to get a compile time error when using queryIID<IEvenMoreDerived>();
as IEvenMoreDerived
doesn't have a static member iid
. I assume it might be possible using some template magic inside function template queryIID()
, but everything I tried didn't solve the issue.
Some additional points:
- Using
constexpr char*
instead ofstatic const char* const
unfortunately seems not possible as according to The MS VS2015 Feature Preview even in VS2015 it won't be supported. - After some digging I came across the C++ Templates FAQ. According to this, member hiding is a "feature" of class templates. I just couldn't figure out how I might use this to solve my problem. Furthermore I don't want the class hierarchy as presented above to be changed to class.
- Among other questions, I found this somewhat similar question on SO, but it didn't entirely match my problem.