我想为BASECLASS和所有派生类设置一个特殊的格式化程序。我有以下课程:
struct BASECLASS { ... };
struct SPECIALFORMAT : BASECLASS { ... }
struct ANOTHERSPECIALFORMAT : BASECLASS { ... }
template <class T>
struct LISTFORMATTER {
list<T> l;
bool format() {
};
}
bool LISTFORMATTER<BASECLASS>::format() { ... }
LISTFORMATTER<BASECLASS> bcFt;
LISTFORMATTER<SPECIALFORMAT> spFt;
LISTFORMATTER<ANOTHERSPECIALFORMAT> aspFt;
bcFt.format(); // <-- ok
spFt.format(); // <-- Calling standard format(), not specialized
aspFt.format(); // <-- Calling standard format(), not specialized
如何为基类和所有继承的类专门化方法?
编辑更喜欢不使用提升。 c ++(不是c ++ 11)
答案 0 :(得分:4)
首先,您需要is_base_of
。如果你不想使用Boost或C ++ 11,那么在这里抓一个:
How does `is_base_of` work?
然后,你可以这样做:
template <bool B> struct bool_ {};
// ...
bool format() { do_format(bool_<is_base_of<BASECLASS, T>::value>()); }
bool do_format(bool_<false>) {
// not inheriting BASECLASS
}
bool do_format(bool_<true>) {
// inheriting BASECLASS
}
顺便说一下,有一种,AFAIK,没有办法非侵入性地进行这种操作,即只需添加专业化。
编辑:实际上,您可以在没有is_base_of的情况下执行此操作:
// ...
bool format() { do_format((T*)0); }
bool do_format(void*) { /* not inheriting */ }
bool do_format(BASECLASS*) { /* inheriting */ }
这是有效的,因为derived-&gt; base是比class-&gt; void更好的转换。
答案 1 :(得分:2)
标签调度可能会有所帮助:
struct BASECLASS { };
struct SPECIALFORMAT : BASECLASS { };
struct ANOTHERSPECIALFORMAT : BASECLASS { };
template <typename T>
struct IsDerivedFromBASECLASS {
static const bool value = false; //std::is_base_of<BASECLASS, T>::value;
};
template <>
struct IsDerivedFromBASECLASS<BASECLASS> { static const bool value = true; };
template <>
struct IsDerivedFromBASECLASS<SPECIALFORMAT> { static const bool value = true; };
template <>
struct IsDerivedFromBASECLASS<ANOTHERSPECIALFORMAT> { static const bool value = true; };
template <class T>
struct LISTFORMATTER {
//list<T> l;
bool format();
};
template <typename T, bool IsABASECLASS>
struct helper_format {
bool operator() (LISTFORMATTER<T>&)
{
// default implementation
return true;
}
};
template <typename T>
struct helper_format<T, false>
{
bool operator() (LISTFORMATTER<T>&)
{
// specialization implementation
return false;
}
};
template<typename T>
bool LISTFORMATTER<T>::format() {
return helper_format<T, IsDerivedFromBASECLASS<T>::value>(*this);
}
答案 2 :(得分:1)
我认为您可以使用enable_if和is_base_of(来自c ++ 11或boost)来执行此操作。