Template type check C++

前端 未结 6 743
日久生厌
日久生厌 2021-01-14 17:48

I have a template function which takes in objects. I need to determine whether the object is derived from a particular base class. If it is derived from the base class, I ne

相关标签:
6条回答
  • 2021-01-14 18:31

    A true template specialization would be even better :)

    class A {
    public:
        char c;
    };
    
    template <typename T> void foo(const T & t)
    {
        std::cout << "this is generic.";
    }
    
    template <> void foo(const A & a)
    {
        std::cout << "this is specialized.";
    }
    
    int main(int argc, char * argv[])
    {
        foo(A());
    
        foo(int());
    }
    
    0 讨论(0)
  • 2021-01-14 18:33

    Boost.TypeTraits boost::is_base_of

    const bool is = boost::is_base_of<Base,Derived>::value;
    

    How does `is_base_of` work?

    0 讨论(0)
  • 2021-01-14 18:35

    Without knowing the exact nature of the additional work you want to do, there could be 2 ways might approach this.

    Option 1: Say the function you want to call is foo(). You could implement foo() on both baseA and testB. baseA::foo() can give you your extra work while testB:foo() would just do nothing. But this style wouldn't make sense if foo() doesn't belong in either of those 2 classes.

    Optional 2: Specialize functionA for baseA (or optionally testB as well)

    void function_specialized(baseA* param)
    {
        // Do your extra work
    
        // Then call the common functionA
        functionA<baseA>(*param);
    }
    
    template<typename T>
    functionA(const T& value)
    {
       //...
    }
    
    0 讨论(0)
  • 2021-01-14 18:40

    You can do template specialization which will be fully static:

    template <typename T>
    void function(const T& value)
    {
      common_task();
    }
    
    template <>
    void function<A>(const A& value)
    {
      common_task();
      // special A tasks
    }
    
    0 讨论(0)
  • 2021-01-14 18:51

    You can use Run Time Type Identification (RTTI) for this purpose. An Example follows:

    class A{
    public:
    virtual void func(){cout << "Base" << endl;}
    virtual ~A(){}
    };
    
    class B:public A{
    public:
    void func(){cout << "Derived" << endl;}
    };
    
    int main(){
    A * d1 = new B();
    B * d2;
    
    d1 -> func() ;
    
    d2 = dynamic_cast<B*>(d1);
    
    if(d2 != NULL)
           cout << "Base exists" << endl;
    else
           cout << "No relation" << endl;
    
    return 0;
    }
    
    0 讨论(0)
  • 2021-01-14 18:54

    It is somewhat difficult to mix templates and inheritance.

    The trouble:

    template <typename T>
    void function(T const& t);
    
    void function(A const& a);
    

    If you use struct B: A {}:, then the template version is preferred, because no conversion is required, and it is therefore a "better" match.

    If you have access to the definition of the template version, you can use a combination of is_base_of and disable_if.

    template <typename T>
    typename boost::disable_if< boost::is_base_of<A, T> >::type function(T const& t);
    

    This simple modification makes use of SFINAE, basically it generates an error when trying to instantiate function for any class derived from A and the C++ standard specifies that if a function may not be instantiated then it is to be removed from the set of overloads considered without triggering a compiler error.

    If you do not have access to the template definition of function, you're out of luck.

    0 讨论(0)
提交回复
热议问题