采用 objects 类型和 objects 所有派生类型的模板函数

template function which takes objects of type and objects of all derived types

我想要一个模板函数,它接受所有 objects,它们是 Base 的实例或来自 Base 的任何派生 classes(这里只有一个派生 class)。我的以下示例不起作用,请参阅评论以了解结果和我想要实现的目标:

#include <iostream>

template <typename T>
class Base { };

template< typename T>
class Derived: public Base<T> { };

//FIRST
template < typename T>
void Do( const T& )
{
    std::cout << "FIRST " << __PRETTY_FUNCTION__ << std::endl;
}

// SECOND Should eat all types which derives from Base<T>
template < typename T>
void Do( Base<T>& base)
{
    std::cout << "SECOND " << __PRETTY_FUNCTION__ << std::endl;
}


int main()
{
    Derived<int> derived;
    Base<int> base;

    Do(base);       // SECOND void Do(Base<T>&) [with T = int]           OK
    Do(derived);    // FIRST void Do(const T&) [with T = Derived<int>]   Fail -> should go to SECOND!
    Do(1);          // FIRST void Do(const T&) [with T = int]            OK
}

原始代码有Base作为模板class。我简化了这一点,但应该记住。

虽然我想用 enable_if 为基础类型和派生类型禁用 FIRST 函数,但我找不到正确技巧的想法。并且只为基础和派生的 classes 启用第二个是一个选项,但我不能在这里得到诀窍。

我看到了 enable_if type is not of a certain template class 但这对派生的没有帮助。

编辑: 抱歉,我给出的例子过于简单了。如标题中所述,我需要一些模板内容来确定模板函数的类型是模板的实例还是派生自该模板类型。我修改了示例代码。

写一个特征来检查 类 派生自 Base:

的任何特化
namespace detail {
    template<class T>
    std::true_type test(Base<T>*);
    std::false_type test(...);
}

template<class T>
struct is_derived_from_Base : decltype(detail::test((T*)nullptr)) {};

并用它来约束第一个函数模板:

template < typename T, typename = std::enable_if_t<!is_derived_from_Base<T>{}> >
void Do( const T& )
{   
    std::cout << "FIRST " << __PRETTY_FUNCTION__ << std::endl;
}