c++ - 使用带有基类的模板作为参数

标签 c++ templates sfinae

我想定义一个模板类,为不同的类型专门化一些方法。

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 派生的新类,并对这些类的对象使用模板特化。当然它编译但不链接,因为缺少每个子类的特化。

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

最佳答案

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

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]

关于c++ - 使用带有基类的模板作为参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37048886/

相关文章:

C++ 网络,recv() 无缘无故失败(?)

C++ 将派生类 shared_ptr 传递给模板函数

c++ - Clang 和 GCC 误推模板参数

c++ - 如何在类模板中使用 boost::enable_if

c++ - 如何解决自动返回类型 - C++(模板)

c++ - g++ 编译器不识别嵌套模板类

c++ - 使用 unordered_map 从两个大文本文件中删除重复项

c++ - 访问结构数组中的 std::unordered_map 时出现浮点错误

c++ - 如何有条件地实例化具有多个模板参数的模板类?

C++ SFINAE 没有失败