Hãy coi chủ đề này là phần tiếp theo của chủ đề sau:
Phần trước
Hành vi không xác định và các điểm trình tự
Hãy xem lại biểu cảm hài hước và phức tạp này (các cụm từ in nghiêng được lấy từ chủ đề trên * smile *):
i += ++i;
Chúng tôi nói rằng điều này gọi hành vi không xác định. Tôi cho rằng khi nói điều này, chúng ta mặc nhiên cho rằng kiểu của i
là một trong những kiểu cài sẵn.
Điều gì xảy ra nếu kiểu của i
là kiểu do người dùng xác định? Giả sử loại của nó Index
được xác định sau trong bài đăng này (xem bên dưới). Nó sẽ vẫn gọi hành vi không xác định?
Nếu đúng thì tại sao? Nó không tương đương với viết i.operator+=(i.operator++());
hoặc thậm chí đơn giản hơn về mặt cú pháp i.add(i.inc());
? Hoặc, họ cũng gọi hành vi không xác định?
Nếu không, tại sao không? Rốt cuộc, đối tượng i
được sửa đổi hai lần giữa các điểm trình tự liên tiếp. Vui lòng nhớ lại quy tắc ngón tay cái: một biểu thức chỉ có thể sửa đổi giá trị của đối tượng một lần giữa các điểm trình tự "liên tiếp . Và nếu i += ++i
là một biểu thức, thì nó phải gọi hành vi không xác định. Nếu vậy, thì tương đương của nó i.operator+=(i.operator++());
và i.add(i.inc());
cũng phải gọi hành vi không xác định mà dường như là không đúng sự thật! (theo như tôi hiểu)
Hoặc, i += ++i
không phải là một biểu thức để bắt đầu? Nếu vậy, thì nó là gì và định nghĩa của biểu thức là gì?
Nếu đó là một biểu thức và đồng thời, hành vi của nó cũng được xác định rõ ràng, thì điều đó ngụ ý rằng số lượng điểm trình tự được liên kết với một biểu thức bằng cách nào đó phụ thuộc vào loại toán hạng liên quan đến biểu thức. Tôi có đúng không (thậm chí một phần)?
Nhân tiện, làm thế nào về biểu hiện này?
//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.
Bạn cũng phải cân nhắc điều này trong phản hồi của mình (nếu bạn biết chắc chắn hành vi của nó). :-)
Là
++++++i;
được xác định rõ trong C ++ 03? Rốt cuộc, đây là cái này,
((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;
}
};