Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cast for upcasting only

We all know that C-style casts are considered evil in C++. Which is why they are replaced by const_cast<>, static_cast<>, and dynamic_cast<> to provide for more bespoke casting, allowing the programmer to only allow the intended classes of conversions. So far, so good.

However, there seems to be no builtin syntax to perform an explicit upcast: A means to perform the otherwise implicit conversion in Base& baseRef = derived explicitly without allowing the reverse.

While I know that this is quite a small corner case (most of the time the implicit conversions work just fine), I was wondering what techniques are available to implement such a cast in user code. I was thinking about something along the lines of

template<class T>
class upcast {
    public:
        template<class U, typename = typename std::enable_if<std::is_convertible<U, T>::value>::type>
        upcast(U value) : value(value) {}
        operator T() { return value; }
    private:
        T value;
};

However, that seems too complicated to be good, and since I'm not an expert in template-metaprogramming, I would like to ask whether there are different/better/simpler approaches.

like image 601
cmaster - reinstate monica Avatar asked Oct 18 '22 04:10

cmaster - reinstate monica


1 Answers

std::forward<T&> will only allow upcasts:

struct A {};
struct B : A {};
A a;
B b;
auto& x = std::forward<A&>(b); // OK
auto& y = std::forward<B&>(a); // fails
auto* px = std::forward<A*>(&b); // OK
auto* py = std::forward<B*>(&a); // fails
like image 58
ecatmur Avatar answered Nov 13 '22 03:11

ecatmur