使用以基数 class 作为参数的模板

Use template with base class as parameter

我想定义一个模板 class,其中包含针对不同类型的一些方法的专门化。

template <typename T>
class Handler {
public:
    void method1() { method2(); }
protected:
    void method2();
}

然后在实现文件中:

template <> Handler<int>::method2() { doSomething(); }
template <> Handler<float>::method2() { doSomethingElse(); }
template <> Handler<ClassB>::method2() { doSomethingDifferent(); }

到目前为止,一切正常。

现在我想定义一些从 ClassB 派生的新 classes,并对这些 classes 的对象使用模板特化。当然它编译但不编译 link,因为缺少每个子 class 的特化。

有没有办法使用这些模板,例如使用 SFINAE?

第一个:

template <class T,class=void>
class Handler

然后使用 SFINAE 创建专业:

template <class T>
class Handler<T,std::enable_if_t<test>>

现在,让该专业化在其主体中包含其实现,或者从实现类型(非模板)继承并在 impl 文件中实现它。

为了您的目的,测试可能是基础。

您的 int impl 现在需要添加一个 ,void 参数。

您还可以使用特征 class 进行条件映射。

我经常发现在类型标签上重载是专门化的一个很好的替代方法:

namespace {

template<class T> struct Type { using type = T; }; // Or boost::type<T>
template<class T> struct TypeTag { using type = Type<T>; };

struct ClassB {};

template <typename T>
class Handler {
public:
    void method1() {
        method2(typename TypeTag<T>::type{}); // Call an overloaded function.
    }
protected:
    void method2(Type<int>) { std::printf("%s\n", __PRETTY_FUNCTION__); }
    void method2(Type<float>)  { std::printf("%s\n", __PRETTY_FUNCTION__); }
    void method2(Type<ClassB>)  { std::printf("%s\n", __PRETTY_FUNCTION__); }
};

// Somewhere else.
struct ClassC : ClassB {};
template<> struct TypeTag<ClassC> { using type = Type<ClassB>; };

} // namespace

int main(int ac, char**) {
    Handler<ClassB> b;
    b.method1();

    Handler<ClassC> c;
    c.method1();
}

输出:

void {anonymous}::Handler<T>::method2({anonymous}::Type<{anonymous}::ClassB>) [with T = {anonymous}::ClassB]
void {anonymous}::Handler<T>::method2({anonymous}::Type<{anonymous}::ClassB>) [with T = {anonymous}::ClassC]