Rozważ ten temat jako kontynuację następującego tematu:
Poprzednia rata
Niezdefiniowane zachowanie i punkty sekwencji
Wróćmy do tego zabawnego i zawiłego wyrażenia (wyrażenia zapisane kursywą pochodzą z powyższego tematu * uśmiech *):
i += ++i;
Mówimy, że wywołuje to niezdefiniowane zachowanie. Przypuszczam, że kiedy powiem, możemy założyć, że niejawnie typu o i
to jeden z wbudowanych typów.
Co zrobić, jeśli typ o i
to typ zdefiniowany przez użytkownika? Powiedz, że jego typ jest Index
zdefiniowany w dalszej części tego postu (patrz poniżej). Czy nadal wywoływałoby niezdefiniowane zachowanie?
Jeśli tak, dlaczego? Czy nie jest to równoznaczne z pisaniem i.operator+=(i.operator++());
lub nawet prostsze składniowo i.add(i.inc());
? A może one również wywołują niezdefiniowane zachowanie?
Jeśli nie, dlaczego nie? W końcu obiekt i
jest modyfikowany dwukrotnie między kolejnymi punktami sekwencji. Przypomnij sobie praktyczną zasadę: wyrażenie może modyfikować wartość obiektu tylko raz między kolejnymi "punktami sekwencji . A jeśli i += ++i
jest wyrażeniem, to musi wywołać niezdefiniowane zachowanie. Jeśli tak, to jego odpowiedniki, i.operator+=(i.operator++());
a i.add(i.inc());
także musi wywołać niezdefiniowane zachowanie, które wydaje się nieprawdziwe! (o ile rozumiem)
A i += ++i
może nie jest to wyrażenie na początek? Jeśli tak, to co to jest i jaka jest definicja wyrażenia ?
Jeśli jest to wyrażenie, a jednocześnie jego zachowanie jest również dobrze zdefiniowane, oznacza to, że liczba punktów sekwencji powiązanych z wyrażeniem zależy w jakiś sposób od typu operandów zaangażowanych w wyrażenie. Czy mam rację (choćby częściowo)?
A propos, co powiesz na to wyrażenie?
//Consider two cases:
//1. If a is an array of a built-in type
//2. If a is user-defined type which overloads the subscript operator!
a[++i] = i; //Taken from the previous topic. But here type of `i` is Index.
Musisz to również wziąć pod uwagę w swojej odpowiedzi (jeśli na pewno znasz jej zachowanie). :-)
Jest
++++++i;
dobrze zdefiniowane w C ++ 03? W końcu to jest to,
((i.operator++()).operator++()).operator++();
class Index
{
int state;
public:
Index(int s) : state(s) {}
Index& operator++()
{
state++;
return *this;
}
Index& operator+=(const Index & index)
{
state+= index.state;
return *this;
}
operator int()
{
return state;
}
Index & add(const Index & index)
{
state += index.state;
return *this;
}
Index & inc()
{
state++;
return *this;
}
};