基类的c ++模板特化

时间:2014-01-29 17:04:06

标签: c++ templates template-specialization

我想为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)

3 个答案:

答案 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)来执行此操作。