【问题标题】:template function which takes objects of type and objects of all derived types模板函数,它接受类型对象和所有派生类型的对象
【发布时间】:2016-01-21 21:53:00
【问题描述】:

我想要一个模板函数,它从 Base 获取所有作为 Base 实例或任何派生类(这里只有一个派生类)的对象。我的以下示例不起作用,请参阅 cmets 了解结果和我想要实现的目标:

#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作为模板类。我简化了这一点,但应该记住。

我虽然关于使用 enable_if 禁用基本类型和派生类型的 FIRST 函数,但我找不到正确技巧的想法。并且还可以选择仅对基类和派生类启用 SECOND ,但我无法在这里获得诀窍。

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

编辑: 抱歉,我给出的示例非常简化。正如标题中给出的,我需要一些模板的东西来确定模板函数的类型是模板的实例还是从这个模板类型派生的。我修改了示例代码。

【问题讨论】:

    标签: c++ c++14 template-meta-programming


    【解决方案1】:

    编写一个特征来检查派生自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;
    }
    

    【讨论】:

    • 好的,我找不到的棘手部分是获得首先是 Base 的 T 并且必须为我的 T 拆分,这是一个 int 以作为 Base .好,我知道了!谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-21
    • 2018-11-05
    • 2020-10-28
    • 1970-01-01
    • 2011-03-22
    • 1970-01-01
    相关资源
    最近更新 更多