2013-08-16 45 views
15

Khi tôi xem xét hai quá tải sau:tham chiếu phổ biến so với ưu tiên tham chiếu const?

template <class... T> void f(const T&... x); 
template <class T> void f(const T& x); 

Tôi có sự đảm bảo rằng f(x) sẽ luôn luôn gọi hàm thứ hai và sẽ không bao giờ dẫn đến một sự mơ hồ. Theo một nghĩa nào đó, phiên bản thứ hai được ưu tiên phổ biến so với phiên bản đầu tiên cho một đối số bất kể loại của nó là gì.

Bây giờ xem xét tình hình, nơi có một tài liệu tham khảo phổ thông và một phiên bản tham chiếu const của một hàm:

template <class T> void f(T&& x); 
template <class T> void f(const T& x); 

Câu hỏi của tôi là: là họ ưu tiên phổ biến giữa hai chức năng này không phụ thuộc vào loại x (tham chiếu giá trị r, tham chiếu, cv-vòng loại, con trỏ ...) như trong trường hợp trước? (và nếu có, ưu tiên là gì?)

+2

Tôi nghĩ đó là [cuộc trò chuyện này] (http://www.youtube.com/watch?v=T5swP3dr190) bao gồm điều này. – chris

Trả lời

17

Không có ưu tiên chung giữa hai chức năng này. Họ cạnh tranh bằng nhau trong thuật toán phân giải quá tải. Nói chung, cái gọi là "tham chiếu chung" thắng trừ khi const T& là kết quả khớp chính xác và có các chiến thắng const T&.

struct A {}; 

int 
main() 
{ 
    f(std::declval<A>()); // calls f<A>(A&&), #1 
    f(std::declval<const A>()); // calls f<const A>(const A&&), #1 
    f(std::declval<A&>()); // calls f<A&>(A&), #1 
    f(std::declval<A&&>()); // calls f<A>(A&&), #1 
    f(std::declval<const A&&>()); // calls f<const A>(const A&&), #1 
    f(std::declval<const A&>()); // calls f<A>(const A&), #2 
} 

lời khuyên tốt là để bao giờ quá tải như thế này.

+0

Nó có thể là đáng nói đến những trường hợp này (nếu có) # 2 không bao giờ là một ứng cử viên để bắt đầu với. –

+0

@BenVoigt Trừ khi tôi đang thiếu một cái gì đó, cả hai quá tải là khả thi trong tất cả các biểu thức này. – aschepler

+0

@aschepler: Tôi nghĩ bạn nói đúng. Có lẽ nó là 'T &&' vs 'T &' mà kết thúc là đáng ngạc nhiên. –