2013-08-16 38 views
15

İki aşağıdaki aşırı yükleri bakmak gerekirse:evrensel başvuru vs const başvuru önceliği?

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

Ben f(x) her zaman ikinci işlevini çağırır ve bir belirsizliğe yol asla garantisi var. Bir anlamda, ikinci versiyon, türü ne olursa olsun, bir argüman için birinci olana göre evrensel olarak önceliklendirilir. Bu iki fonksiyon arasında evrensel bir öncelik bakılmaksızın x türünden (onların geçerli:

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

Sorum şu:

Şimdi evrensel bir referans ve bir fonksiyonun const referans versiyonları var durum dikkate r-değeri referansı, referans, cv-niteleyiciler, işaretçi ...) önceki durumda olduğu gibi? (ve eğer evet ise, öncelik nedir?)

+2

Bunu içeren bu konuşmanın (http://www.youtube.com/watch?v=T5swP3dr190) olduğunu düşünüyorum. – chris

cevap

17

Bu iki işlev arasında evrensel bir öncelik yoktur. Aşırı yük çözünürlüğü algoritmasında eşit olarak rekabet ederler. Genel olarak, sözde "evrensel referans", const T& tam olarak eşleşmediği sürece kazanır ve const T& kazanır.

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 
} 

İyi tavsiye böyle asla aşırı etmektir.

+0

Bu davalardan hangisinin (varsa) # 2'nin başlangıçta asla aday olmayacağından bahsetmeye değer olabilir. –

+0

@BenVoigt Bir şey kaçırmadıkça, tüm bu ifadelerde aşırı yüklenmeler uygulanabilir. – aschepler

+0

@aschepler: Sanırım haklısınız. Belki de 'T &' 'vs' T & 'şaşırtıcıdır. –