Предполагая следующую иерархию классов:Force ошибка компиляции на отсутствие статической переменной-члена в производных классах
//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
Каждый класс в этой иерархии должны иметь свои собственные static const tChar* const iid
, которые могут быть использованы для идентификации объекта без инстанцировании его. В IEvenMoreDerived
эта информация отсутствует.
Теперь, где-то в коде, у меня есть шаблон функции, где осуществляется доступ к IID:
//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;
}
Мое намерение состоит в том, чтобы получить ошибку во время компиляции при использовании queryIID<IEvenMoreDerived>();
в IEvenMoreDerived
не имеет статический член iid
. Я предполагаю, что это возможно, используя шаблон шаблона шаблона внутри шаблона queryIID()
, но все, что я пробовал, не решило проблему.
Некоторые дополнительные пункты:
- Использование
constexpr char*
вместоstatic const char* const
, к сожалению, кажется, не представляется возможным в соответствии с The MS VS2015 Feature Preview даже в VS2015 это не будет поддерживаться. - После некоторого рытья я наткнулся на C++ Templates FAQ. В соответствии с этим, скрытие элемента является «функцией» шаблонов классов. Я просто не мог понять, как я могу использовать это, чтобы решить мою проблему. Кроме того, я не хочу, чтобы иерархия классов, представленная выше, была изменена на класс.
- Среди других вопросов я нашел this somewhat similar question on SO, но это не полностью соответствовало моей проблеме.
Похоже, что решение ищет проблему для меня. Если ваши IID необходимы и вы их не определяете, компилятор и/или компоновщик рано или поздно пропустят их. В лучшем случае вы замените подлинную ошибку компилятора/компоновщика с ошибкой ошибок шаблона über. –
Может ли 'typeid' помочь здесь? – sharptooth
Вы не можете идентифицировать OBJECT без создания экземпляра, по определению объектом является создание класса CLASS. – Rugruth