2017-09-19 110 views
14
template <typename T> 
T go(T a, T *b){ T *t; return *t;} 

int main() { 
    const int x = 10; 
    go(x, &x); 
    return 0; 
} 

derleyici hatası verir?Şablon argüman kesinti arızası

Bu derleme hatasını düzeltmek için , go<const int>(x, &x); argümanlarının türünü belirterek derleyici kesinti işlemini geçersiz kıldı, ancak yine de neden bunu yapmak gerekir?

cevap

13

Bu tür bir kesinti çakışması var. T, ilk bağımsız değişkenden int ve ikinci bağımsız değişkenden const int olarak çıkarılır. Bu nedenle, tür kesinti başarısız olur (ve derleyici, altta yatan nedenin açıklığa kavuşmasına neden olan veya olmayan bir mesaj sunar).

açıkça şablon argümanı belirtmek zorunda kalmadan bu fonksiyon çalışmalarını yapmak istiyorsanız sadece ikinci fonksiyon argümanı kesinti yönlendirmesi için bunu yapabiliriz:

template <class T> 
struct NonDeduced { using type = T; } 

template <class T> 
T go(typename NonDeduced<T>::type a, T *b) { T *t; return *t; } 

O yol, T sadece olacak ikinci argümandan çıkarılabilir ve ilk parametre değiştirilmeden T değerini kullanır.

+1

Teşekkürler, bu ilginç, ama bunu dahili olarak gerçekleştirir hile göz önünde bulundurarak iyi bir programlama uygulama olacağını düşünüyorsunuz: clang bunun için oldukça açık bir mesaj veriyor. –

+0

@SauravSahu Şablonlarla ilgili önemli olmayan şeyler yapmaya başladığınızda, böyle bir "NonDeduced" bir yere sahip olmanız gerekir. Ve bir kez sahip olduğunuzda, onu da kullanabilirsiniz. Bu özel durumda iyi bir fikir olup olmadığı ya da işlerin farklı bir şekilde yapılıp yapılamayacağı, büyük ölçüde gerçek kullanım durumunuzda gerçekte ne yaptığına bağlıdır. – Angew

6

atemplate argument deduction sonra, değer geçirilecek ilan Çünkü: go(x, &x); için anlamı

c) otherwise, if A is a cv-qualified type, the top-level cv-qualifiers are ignored for deduction:

, 1 argüman x için, şablon parametresi Tint değil const int olarak çıkarılabilir edilecektir. İkinci argüman için Tconst int olarak çıkarılacaktır, çünkü b işaretçi tarafından iletileceği bildirilir (ve işaret edilen nesnede cv-niteleyiciler ayrılmıştır; aynı şey, başvuru için yapılır). Sonra kesinti başarısız olur.


BTW:

prog.cc:4:3: note: candidate template ignored: deduced conflicting types for parameter 'T' ('int' vs. 'const int')

+0

Bence OP, clang mesajının verdiği içgörüye ulaştı. Bunun neden olduğunu sordu – sehe

+0

@sehe Hata mesajının * yanlış * bölümüne odaklanmış gibi görünüyor; Şablon kesinti çelişkisi hakkındaki hata mesajının daha fazla yardımcı olacağını OP'ye söylemek istiyorum. – songyuanyao