9

Tôi muốn để có thể viết một cái gì đó dọc theo những dòng:Có hợp pháp khi sử dụng các mẫu variadic trong quá tải toán tử không?

struct bar {}; 

template <typename ... Args> 
bar operator+(bar, Args ...) 
{} 

tôi chỉ kiểm tra với kêu vang/gcc và các nhà điều hành quá tải được nhặt cả bởi biểu thức nhị phân (a+b) và biểu thức unary (+a), như tôi mong đợi. Tuy nhiên các toán tử bị hạn chế nhiều hơn các hàm bình thường, theo nghĩa - ví dụ - bạn không thể quá tải operator+() với ba đối số.

Việc sử dụng trên hợp pháp và di động phải không?

EDIT Để đưa ra một chút ngữ cảnh, tôi rõ ràng không mong đợi để có thể xác định các toán tử variadic hoặc bất kỳ thứ gì sắp xếp. Lý do tôi quan tâm đến điều này là cho một hack xấu xí: Tôi muốn làm cho một số nhà khai thác variadic để tôi có thể "ghi đè" chúng với triển khai non-variadic khác. Vì các mẫu variadic được coi là ít chuyên biệt hơn các mẫu không phải là variadic trong các quy tắc nạp chồng mẫu chức năng, tôi có thể ghi đè lên toán tử variadic bằng một toán tử không phải là variadic. Có nó khá ghê tởm :)

Trả lời

5

Trước hết, định nghĩa tốt, bởi vì có tồn tại các chuyên ngành hợp lệ với các gói không rỗng .

Bây giờ, các biểu thức cụ thể a+b hoặc +a là i.a. chuyển thành cuộc gọi không phải là thành viên của biểu mẫu operator+(a, b)operator+(a), tương ứng ([over.match.oper]/2). Tra cứu tên sau đó tìm mẫu chức năng toán tử, có chuyên môn hóa trở thành một phần của ứng cử viên. Cuối cùng, [over.match.oper]/6 chỉ các đại biểu đến quá tải độ phân giải như thường lệ:

Tập hợp các chức năng ứng cử viên cho giải quyết tình trạng quá tải là sự kết hợp của các ứng viên thành viên, các ứng viên phi thành viên, và được xây dựng trong ứng cử viên. Danh sách đối số chứa tất cả các toán hạng của toán tử . Chức năng tốt nhất từ ​​bộ chức năng ứng cử viên là được chọn theo 13.3.2 và 13.3.3.

Mã của bạn cũng sẽ hoạt động như dự định, vì quá trình phân giải quá tải và đặt hàng một phần sẽ tôn trọng mẫu chức năng của nhà điều hành.


tuyên bố trên cho các nhà khai thác unary, ngoại trừ có lẽ postfix --++, là vô hình thành, không có chẩn đoán cần thiết. Cf. [temp.res]/(8.2).

+0

Cảm ơn bạn đã trả lời, tôi đã thêm một chút ngữ cảnh vào câu hỏi gốc. – bluescarni

+0

@bluescarni Yeah, được rồi. – Columbo

3

Các tiêu chuẩn hạn chế số lượng đối số (và sự hiện diện của các đối số mặc định) cho hàm operator s, trong [over.oper]:

8 - Một chức năng điều hành không thể có đối số mặc định ([dcl.fct. mặc định]), trừ khi được nêu rõ dưới đây. Các hàm vận hành 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.

Tuy nhiên, những gì bạn đã khai báo là mẫu chức năng điều hành , không có giới hạn nào như vậy. Điều này có nghĩa là mã của bạn là tốt; việc sử dụng đơn nhất hoặc nhị phân + sẽ được chuyển thành một cuộc gọi đến operator+ với một hoặc hai đối số và việc tạo mẫu thích hợp cho mẫu của bạn sẽ được tạo tương ứng.

Nó sẽ là bất hợp pháp nếu bạn đã chuyên hoặc dứt khoát nhanh chóng các chức năng điều hành mẫu với một số bất hợp pháp của các đối số, vì ([over.oper]):

1 - [... ] Một chuyên môn về mẫu hàm vận hành cũng là một hàm toán tử . [...]


Lưu ý rằng một hiệu ứng tương tự có được nếu chúng ta viết một nhà điều hành phi variadic hàm mẫu có thể được khởi tạo với các loại không chính xác:

template<class T> int operator+(T, T) { return 0; } // OK 
struct bar {}; template int operator+(bar, bar);  // OK 
template int operator+(int, int);     // Error is here 
Các vấn đề liên quan