2016-12-16 25 views
8

Với 3 quá tải sauquá tải của mẫu chức năng với tính năng tự

template <class T> auto foo() { return 1; } 
template <class T> int foo() { return 2; } 
template <class T> T foo() { return 3; } 

như sau ốm hình thành?

static_cast<int(*)()>(&foo<int>)(); 

Clang chọn quá tải # 2, trong khi gcc thất bại trong việc biên dịch (Demo)

Khi tháo quá tải # 1, cả hai đồng ý để chọn quá tải # 2 (Demo).

Khi tháo quá tải # 2, gcc Selects quá tải # 1 và kêu vang không biên dịch (Demo)

+6

Không xác định 1 và 2 trong cùng đơn vị dịch thuật là vi phạm ODR? – user657267

+0

Nếu "tự động" được dịch là "int" thì # 1 và # 2 giống nhau, có? Không thích ứng cử viên. Clang dường như xem xét hơn 2 chuyên ngành hơn # 1 và # 1 và # 3 cùng chuyên môn; lựa chọn mơ hồ một lần nữa. Tôi sẽ nói rằng gcc là đúng và Clang là sai do "tự động" không nên tham gia vào các độ phân giải quá tải. – Ripi2

+2

@ user657267 Các loại trả về là một phần của chữ ký của mẫu chức năng. Các khai báo trên cung cấp các loại trả về * khai báo * khác nhau, vì vậy chữ ký khác nhau. Rằng các loại trả về thực tế trùng với không liên quan. – Columbo

Trả lời

8

Theo [over.over]/2, chúng tôi thực hiện khấu trừ mẫu tranh cãi. Điều này sẽ thành công cho cả ba tình trạng quá tải: trong lần đầu tiên, giữ [temp.deduct.funcaddr]/2 trong tâm trí:

Loại trình giữ chỗ (7.1.7.4) trong kiểu trả về của mẫu chức năng là một ngữ cảnh không được suy luận. Nếu mẫu khấu trừ đối số thành công cho một hàm như vậy, kiểu trả về được xác định từ sự khởi tạo của cơ quan chức năng .

Do khấu trừ sẽ thành công (với tất cả các tham số mẫu đã cung cấp đối số rõ ràng), kiểu trả về được suy ra là int. Trong trường hợp thứ hai, khấu trừ thành công kể từ khi đối số được cung cấp và trong phần thứ ba, T sẽ được khấu trừ. & dagger;

Đi vào paragraph 4,

Nếu có nhiều hơn một chức năng được chọn, [...] bất kỳ trao chức năng mẫu chuyên môn F1 được loại bỏ nếu tập chứa một giây chức năng mẫu chuyên môn có chức năng mẫu là chuyên biệt hơn mẫu chức năng của F1 theo các quy tắc đặt hàng một phần của 14.5.6.2 . Sau khi loại bỏ như vậy, nếu có, sẽ vẫn chính xác một chức năng được chọn.

Theo [temp.deduct.partial]/3, các loại chức năng của mẫu chức năng được sử dụng để đặt hàng một phần. Chúng ta có thể thấy ngay rằng các kiểu hàm số 1 và # 2 không chứa bất kỳ tham số mẫu nào tham gia khấu trừ, do đó, thông qua việc thêm vào số [temp.deduct.partial]/4 được giới thiệu bởi vấn đề cốt lõi của độ phân giải 1391, tương ứng của chúng P s không được sử dụng để xác định thứ tự. @ bogdan giải thích here lý do tại sao độ phân giải đó có vấn đề; dòng dưới cùng là thứ tự chỉ mang lại một sự mơ hồ cho # 1 và # 2.

Tức là, theo từ ngữ hiện tại (có thể bị lỗi), việc chuyển đổi không đúng định dạng trong mọi trường hợp. Nếu đặt hàng một phần được cố định cho các cặp tham số không phụ thuộc/khấu trừ, thì

  • trường hợp 1 và 3 không rõ ràng, bởi vì đối với hai loại chức năng không phụ thuộc (loại # 1 và # 2), không có cặp đặt hàng.
  • hành vi chấp nhận trong trường hợp 2 là chính xác (như mong đợi).

& dagger;[temp.deduct.type]/8 yếu tố 9 (T()), trong trường hợp bạn tò mò.

+0

Chapeau. Thật sự thú vị. Bạn biết tiêu chuẩn của trái tim và nó sợ tôi một chút anyway ... :-) +1 – skypjack

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