Runtime std::conditional

124 Views Asked by At

I have polymorphic classes Base, Derived1 and Derived2.

I want to make

bool b = typeid(*base) == typeid(Derived1);

dynamic_cast<typename std::conditional<b, Derived1*, Derived2*>::type>(base)

My compiler says that b is not a compile time expression (and I understand what this means). Is there a way to solve the problem?

1

There are 1 best solutions below

16
463035818_is_not_an_ai On BEST ANSWER

You do not need std::conditional here. As you are making a dynamic cast, this cast happens at runtime anyhow, so theres no point in trying to push it into compile time. Just remove std::conditional and the problem is gone:

if (b) 
   dynamic_cast<Derived1*>(base)
else 
   dynamic_cast<Derived2*>(base)

Note that this code is as pseudo as yours and that chances are high that you do not need a cast in the first place. Maybe you do, but without context I guess that you rather need a virtual function.

Moreover, bool b = typeid(*base) == typeid(Derived1); looks like you want to cast to Derived1* only when the cast would suceed. However, dynamic_cast does already tell you when a cast cannot be made by returning a nullptr.


If you are looking for a way to "hide" the cast in a function, this isnt going to work. If you write a base* my_cast(auto* x) as you mention in a comment, it will always return a base* no matter what you cast inside the function:

#include <iostream>
#include <type_traits>

struct base { 
    virtual ~base() {}
    void hello() { std::cout << "base\n";} // not virtual
};

struct derived : base {
    void hello() { std::cout << "derived\n";}
};

base* foo(auto* b) {
    auto d = dynamic_cast<derived*>(b);  // cast to derived  
    d->hello();
    return d;                            // and return
}

int main() {
    base b;
    auto x = foo(&b);
    std::cout << std::is_same<base*,decltype(x)>::value << "\n";
    std::cout << std::is_same<derived*,decltype(x)>::value << "\n";
    x->hello();
}

Output is:

derived
1
0
base