Только для трансляции

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

Однако, кажется, нет встроенного синтаксиса для выполнения явного upcast: A означает выполнить явно неявное преобразование в 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;
};
</class></class>

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

1 ответ

std::forward будет разрешать только 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
</b*></a*></b&></a&>

licensed under cc by-sa 3.0 with attribution.