Перегрузка эталонного приведения C++ (понижающее наследование)

Можно ли перегрузить приведение ссылок в C++?

У меня есть код, который я не могу трогать в формате:

void someMethod(Parent& parentReference, ...){
    ...
    Child& child = static_cast<Child&>(parentReference);

(Класс Child наследуется напрямую и публично от класса Parent)

Я хотел бы настроить поведение этого приведения — я могу изменить класс Child.
Я пытался перегрузить оператор приведения следующим образом:

Parent::operator Child&(){
    ...

Но этот метод никогда не вызывается.

Я начинаю задаваться вопросом, возможно ли это вообще?

EDIT
Согласно R Sahu, я близок к такому сценарию: https://timsong-cpp.github.io/cppwp/n3337/expr.static.cast#2

struct B { };
struct D : public B { };
D d;
B &br = d;

static_cast<D&>(br);            // produces lvalue to the original d object

За исключением того, что вместо простого присвоения B &br = d;, br входит в метод в качестве аргумента и предварительно отправляется по сети (как NML).

Это будет сценарий:

struct B { };
struct D : public B { 
   int a;
   int b
};

D d;
d.a = x;
d.b = y;

server.send(d); 

...

client.receive(msg);

receive(B& msg){

  D& msgD = static_cast<D&>(msg);

}

msgD.x и msgD.y передаются по проводам и реконструируются должным образом. Однако я хотел бы изменить способ их реконструкции, не изменяя метод receive. Это возможно?


person fatman    schedule 19.09.2017    source источник
comment
Если вы не можете изменить Parent, то компилятор не должен даже позволять вам определять Parent::operator Child&().   -  person Brian Bi    schedule 19.09.2017
comment
Возможный дубликат Можно ли перегрузить оператор *static_cast*?   -  person Fantastic Mr Fox    schedule 19.09.2017
comment
@Brain - да, это была ошибка - я отредактировал соответственно. На самом деле я могу изменить Parent.   -  person fatman    schedule 19.09.2017
comment
вам нужно изменить реконструкцию, так что сделайте это. обычно это называется десериализацией. или покажи нам, как это делается   -  person Andriy Tylychko    schedule 21.09.2017


Ответы (1)


Данные классы

struct Parent
{
};

struct Child : Parent
{
};

static_cast<Child&> не будет использовать определяемую пользователем функцию преобразования.

Из 5.2.9 Static cast/2

Значение lvalue типа «cv1 B», где B — тип класса, может быть приведено к типу «ссылка на cv2 D», где D — класс, производный от B, если допустимо стандартное преобразование из «указателя на D» в « указатель на B» существует, cv2 имеет ту же cv-квалификацию, что и cv1, или большую cv-квалификацию, чем cv1, и B не является ни виртуальным базовым классом D, ни базовым классом виртуального базового класса D. Результат имеет тип «cv2 D».

а затем есть пункты «иначе» в 5.2.9 Static cast/4 и 5.2.9 Статическое приведение/ 5.

Моя интерпретация вышеизложенного заключается в том, что, поскольку Child является подтипом Parent, пункты 4 и 5 выше не применяются.

person R Sahu    schedule 19.09.2017
comment
Тогда почему Child child3 = static_cast<Child>(parent); звонит Parent::operator Child&(){... - person fatman; 19.09.2017
comment
@fatman, я немного обновил ответ. static_cast<Child> отличается от static_cast<Child&>. - person R Sahu; 19.09.2017
comment
@R Саху - спасибо за ответ - это помогло пролить свет именно на то, что я пытаюсь сделать. Я добавил больше деталей к моему вопросу выше. - person fatman; 21.09.2017