c++ - 选择专用于派生实例基类的类模板

标签 c++ templates

考虑以下示例程序:

#include <iostream>

template<typename T>
struct Dispatch
{
    static void send(T&) { std::cout << "unknown\n"; }
};

struct Processor
{
    template<typename T>
    void process(T&& t) { Dispatch<T>::send(t); }
};

template<typename T>
struct Base
{};

template<typename T>
struct Dispatch<Base<T>>
{
    static void send(Base<T>&) { std::cout << "base\n"; }
};

struct Deriv : Base<int>
{};

int main()
{
    Processor p;
    p.process(Base<int>{}); // prints "base"
    p.process(Deriv{});     // prints "unknown"
    return 0;
}

调用Processor::process()时用Deriv实例(这是一个 Base 子类),我想要 Dispatcher()专门用于 Base要选择的类模板。

但是,在上面的示例中,会发生以下情况:

  • 通过 Base<T>实例到 process()调用 Base<T>特化
  • 通过 Deriv实例到 process()调用初级类模板

问题:

  • 为什么是Base<T>不是 Deriv 的更好特化比主要类模板?
  • 有没有通用的方法来调用 Base<T>通过时的特化Base<T>子类?

最佳答案

使用 SFINAE,您可以:

// Traits to detect inheritance:
template <typename T> std::true_type derive_from_base_impl(Base<T>*);
std::false_type derive_from_base_impl(...);

template <typename T>
using derive_from_base_t = decltype(derive_from_base_impl(std::declval<T*>()));

然后是一些变化

template<typename T, typename Enabler = void>
struct Dispatch
{
    static void send(T&) { std::cout << "unknown\n"; }
};

template<typename T>
struct Dispatch<T, std::enable_if_t<derive_from_base_t<T>::value>>
{
    static void send(T&) { std::cout << "base\n"; }
};

Demo

关于c++ - 选择专用于派生实例基类的类模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50593394/

相关文章:

c++ - 使用 OpenCV 计算物体的面积

c++ - 为什么人们在 openmp 循环之前声明迭代值?

templates - Kohana Framework 3.3 中的模板化

C++ 函数模板导致输入参数出错

templates - Twig:否定包含运算符 IN

c++ - 带有默认模板参数的友元函数模板

c++ - 如何在模板中定义迭代器?

c++ - 通过引用传递——为什么要调用这个析构函数?

c++ - 字符数组末尾的额外字符 (char *Result = new char) 8OI

c++ - libgit2 - 两个文本 blob 的差异