11

Trong mã sau, tôi đã cung cấp đối số mặc định cho toán tử chỉ số mảng.Cung cấp các đối số mặc định cho toán tử chỉ số và toán tử gọi hàm

struct st 
{ 
    int operator[](int x = 0) 
    { 
     // code here 
    } 
}; 

Nhưng, trình biên dịch tạo ra một lỗi:

error: 'int st::operator[](int)' cannot have default arguments 
    int operator[](int x = 0) 

Nhưng, Nếu tôi cung cấp đối số mặc định cho chức năng gọi điều hành.

struct st 
{ 
    int operator()(int x = 0) 
    { 
     // code here 
    } 
}; 

Nó hoạt động tốt.

Vì vậy, tôi có một câu hỏi:

  • đối số mặc định Tại sao không cho phép các nhà điều hành mảng subscript?
  • Tại sao các đối số mặc định được phép cho toán tử gọi hàm?
+5

Bởi vì chức năng cuộc gọi có thể có bất kỳ số lượng đối số, trong khi mảng subscripting luôn có một. – interjay

+5

Tôi không thể tưởng tượng bất kỳ việc sử dụng nào cho "subscript mặc định". – molbdnilo

+1

Điều gì sẽ 'x []' có nghĩa là trong trường hợp này? – glglgl

Trả lời

13

Tiêu chuẩn nêu rõ điều đó.

Đối số mặc định không được phép trong operator overloading trong số subscripting operator.

Chức năng của nhà điều hành không thể có đối số mặc định, trừ khi được nêu rõ dưới đây. Các hàm toán tử không thể có nhiều hoặc ít tham số hơn số được yêu cầu cho toán tử tương ứng, như được mô tả trong phần còn lại của điều này.

operator[] sẽ là một hàm thành viên không tĩnh với chính xác một tham số.

Trong khi cho function call operator

operator() chịu một hàm thành viên không tĩnh với một số tùy ý các thông số. Nó có thể có đối số mặc định.

Các toán tử bị quá tải cố gắng tuân theo hành vi tương tự của các trình tích hợp sẵn; với toán tử chỉ số tích hợp, chỉ số (chỉ một) luôn được yêu cầu, nó không có đối số mặc định . Sau đó, toán tử quá tải không được phép có đối số mặc định. Mặt khác, các hàm luôn tốt để lấy số tham số tùy ý và có đối số mặc định.

+2

Câu trả lời này tốt hơn câu trả lời của tôi. Nó đưa ra một tuyên bố rõ ràng từ tiêu chuẩn luôn vượt trội hơn các đặc tả ngữ pháp. – Jodocus

+0

@Jodocus Các đặc điểm ngữ pháp đến cùng một kết luận chắc chắn. Thật may mắn là có những tuyên bố rõ ràng như vậy trong tiêu chuẩn. – songyuanyao

+1

Đó là sự thật. Nhưng hãy xem xét trường hợp ngược lại nơi ngữ pháp cho phép một cái gì đó bị cấm một cách rõ ràng trong tiêu chuẩn. Những trường hợp này tồn tại và đưa ra một lý do khó giải thích tại sao các phát biểu rõ ràng luôn mạnh hơn các câu lệnh ngữ pháp. – Jodocus

13
  • Tại sao không cho phép đối số mặc định cho khai thác mảng subscript?
  • Tại sao đối số mặc định được phép cho toán tử gọi hàm?

Chủ yếu là vì ngữ pháp C++ nói như vậy. Theo A.4 [gram.expr]:

postfix-expression --> postfix-expression [ expr-or-braced-init-list ] 
        --> postfix-expression (expression-list opt) 
        --> simple-type-specifier (expression-list opt) 
        --> typename-specifier (expression-list opt) 

Các thông số cho niềng răng là không bắt buộc, những người cho dấu ngoặc không. Như được đề xuất trong nhận xét, lưu ý rằng các dấu ngoặc được yêu cầu lấy chính xác một thông số trong khi các dấu ngoặc có thể lấy số tham số tùy ý.

Cũng xem xét câu trả lời của songyuanyao cho một tuyên bố rõ ràng từ tiêu chuẩn.

+8

Câu trả lời này rất tuyệt. Nó có thể được cải thiện bằng cách lưu ý rằng '[]' phải lấy chính xác 1 tham số, không ít hơn, ít rõ ràng hơn để đọc tiếng Anh. – Yakk

1

Các nhà khai thác (cả quá tải của người dùng định nghĩa-loại và với nhiều loại inbuilt) nhằm mục đích để cho mọi người sử dụng ký hiệu quen thuộc từ toán học, logic và sử dụng chung (mặc dù <<>> đã thấy hai dịch vụ như nhà khai thác trực tuyến, và các thỏa hiệp không hợp lý phải được thực hiện do các ký tự hạn chế gần như có sẵn trên máy tính). Để quay lại và cho phép các biến thể trên các ký hiệu trực quan, quen thuộc (như đối số ngụ ý) có vẻ ngược lại.

operator() là khác nhau mặc dù ở đó nó có để trừu tượng đi sự khác biệt giữa "gọi" (thông qua) một đối tượng và gọi một hàm cứng mã hóa - nó cần hỗ trợ đối số mặc định để làm điều đó đúng.

2

Tôi cho rằng bạn đang thực sự yêu cầu lý do tại sao tiêu chuẩn cho phép một và không phải loại kia. Lý do chủ yếu liên quan đến những gì mọi người mong đợi, thay vì một số logic kỹ thuật ngăn cản một trường hợp mặc định trong một trường hợp nhưng không phải là khác:

Đó là vấn đề mà người dùng mong đợi. Thông thường, nó có nghĩa là "Lấy phần tử tại [...]" trong đó chúng tôi sử dụng một loại int hoặc một số loại khác để thực hiện một truy vấn cụ thể về một thành viên của một bộ sưu tập. Chúng tôi luôn quan tâm đến việc hỏi về một thành viên cụ thể và chúng tôi luôn có một truy vấn cụ thể trong đầu.

Bây giờ, hãy xem xét ý nghĩa của đối số mặc định. Thường thì nó có nghĩa là "bạn có thể chỉ định điều này, nhưng nếu không tôi sẽ giả định điều này mặc định". Điều này phù hợp với một số chức năng nhất định và mọi người quen với nó.

Thay đổi này có lẽ sẽ làm cho rất nhiều người làm xước đầu họ khi họ nhìn thấy int x = vec[]

Các vấn đề liên quan