假设以下类层次结构:
//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中也不支持。答案 0 :(得分:1)
作为一种变通方法,您可以将Id
委托给外部结构,例如:
template <typename T>
struct IdName
{
static const char* const IID;
};
// instead of `const char* const IBase::IID = "IBase";`
// you have to use the following
template <> const char* const IdName<IBase>::IID = "IBase";
// Same for IDerived
template <> const char* const IdName<IDerived>::IID = "IDerived";
尝试使用IdName<IEvenMoreDerived>::IID
时出现链接错误。