Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I know if a polymorphic object implements an arbitrary abstract class?

Tags:

c++

c++11

This question came up in a class I was attending. Consider:

class foo{virtual void foo_fun() = 0;};

class bar{virtual void bar_fun() = 0;};

template<typename T>
bool is_a_bar(T* f) {
    // I don't know baz.
    // Can I somehow know if f implements bar, T being any other type?
}

class baz : public foo, public bar {
    void foo_fun() override {}
    void bar_fun() override {}
};

#include <iostream>

int main() {
    foo* a{new baz};
    if (is_a_bar(a))  // Will call is_a_bar(foo*)
        std::cout << "a is also a bar\n";
}

Is it possible to know if an arbitrary object, deriving from foo or bar, also derives from the other...without knowing what the actual object is?

(Assume that I can't change foo or bar to provide this information.)

like image 997
Cássio Renan Avatar asked Dec 03 '25 16:12

Cássio Renan


2 Answers

I must admit I'm not entirely sure this is what you're looking for, but you can reduce the candidacy of said-function to only play nice with polymorphic classes using SFINAE, and utilize dynamic_cast<> to query what you're looking for.

Something like:

template<typename T>
typename std::enable_if<std::is_polymorphic<T>::value,bool>::type
is_a_bar(T* f)
{
    return dynamic_cast<bar const*>(f) != nullptr;
}

Any use of void* or some non-polymorphic T will puke at compile-time (and that obviously includes void).

Best of luck.

like image 78
WhozCraig Avatar answered Dec 06 '25 06:12

WhozCraig


If you compile your code with RTTI you can use dynamic_cast:

template<typename T>
bool is_a_bar(T* f) {
    return dynamic_cast<bar*>(f) != nullptr;
}
like image 41
Ron Kuper Avatar answered Dec 06 '25 08:12

Ron Kuper