2016-08-08 3 views
4

Мы все знаем, что касты C-стиля считаются злыми на C++. Именно поэтому они заменяются на const_cast<>, static_cast<> и dynamic_cast<>, чтобы обеспечить более персонализированное литье, позволяя программисту разрешать только предполагаемые классы конверсий. Все идет нормально.Только для повышения рейтинга

Однако, по-видимому, нет встроенного синтаксиса для выполнения явных вентиляционный: Средство для выполнения иначе неявного преобразования в явном виде Base& baseRef = derived, не допуская обратные.

Хотя я знаю, что это довольно маленький угловой случай (в большинстве случаев неявные преобразования работают очень хорошо), мне было интересно, какие методы доступны для реализации такого рода в коде пользователя. Я думал о чем-то вдоль линий

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; 
}; 

Однако, что кажется слишком сложным, чтобы быть хорошими, и так как я не специалист в шаблоне-метапрограммировании, я хотел бы спросить, есть ли другие/лучше/более простые подходы.

+2

Я не уверен, что вы пытаетесь достичь здесь. Вы можете использовать static_cast для повышения. –

+0

Вы не можете перетащить 'reference' с' dynamic_cast' или любым другим актом, потому что 'reference' не может быть' null', поэтому нет способа сказать, что это был upcast действительный или нет. – LibertyPaul

+2

@LibertyPaul Я не уверен, что вы имеете в виду. Ускорение с помощью 'dynamic_cast' всегда выполняется успешно, а плохое downcast будет бросать' std :: bad_cast' при использовании ссылок. – TartanLlama

ответ

2

std::forward<T&> только позволит сбросов:

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