2017-08-25 81 views
6

C++ şablonları hakkında bir sorum var. Aşağıdaki kodlar segfaults.C++ şablonları içinde segfault

template <typename T1, typename T2> 
inline T1 const& max(T1 const &a, T2 const &b) { 
    return a < b ? b : a; 
} 
int main() { 
    std::cout << max(4.9, 4) << std::endl; 
} 

Ancak & kaldırmak ve doğru olanı yapar.

template<typename T1, typename T2> 
inline T1 const max(T1 const &a, T2 const &b) { 
    return a < b ? b : a; 
} 
int main() { 
    std::cout << max(4.9, 4) << std::endl; 
} 

Ayrıca, T1 ve T2 yerine T'yi kullanın ve gayet iyi çalışır.

template<typename T> 
inline T const& max(T const &a, T const &b) { 
    return a < b ? b : a; 
} 

int main() { 
    std::cout << max(4, 5) << std::endl; 
} 

Burada yanlış yapıyorum?

+0

Lütfen kullandığınız sürüm numarası dahil olmak üzere derleyiciden bahset. Eğer GCC ise, -Wall' ile derlediniz mi? Tanımlanmamış davranışlara neden olan görmezden geleceğiniz konusunda bir uyarı olabilir. –

+0

Derleyici, max() çağrısının geçici olarak başvurusunu döndürdüğünü bildirmelidir. – tristan

+1

İlk iki kod parçacığı aynı mıdır? – asimes

cevap

10

Her zaman uyarılar açıkken derlemelisiniz, bkz. https://wandbox.org/permlink/KkhFOJw6QNJ7rv7J. Eğer uyarı bayraklarına sahip olsaydınız, derleyici size yardımcı olur ve size ne yaptığınızı anlatırdı.

Burada olup bitenler bir tanıtımdır (bkz. Return type of '?:' (ternary conditional operator)), bir üçlü ifadeyi bir int ve double üzerinde çalıştırıyorsunuz. Bunu yapmak, geçici olarak tanıtılan double ile sonuçlanır. Ve bir geçici referansa dönme ve ömrünün sınırlanmış geri dönüşlerin olduğu işlevden sonra tanımlanamayan bir davranış olduğunu belirtir.

1

İlk önce, bir referansa geçici olarak dönüyorsunuz.

Neden? Şey, işleviniz T1 türünü döndürüyor, ancak gönderdiğiniz türlerden birini dönüştürmeniz gerekecek. Dönüştürme, doğru türden bir geçici oluşturur. Öyleyse geri veriyorsun.

Geçici olarak öldüklerinden, döndürülen başvuru bir ölü nesneye bağlanır.

Zaten bir düzeltme tespit ettiniz. Ya bir referans döndürmüyorsunuz ya da aynı türden parametreler alıyorsunuz.

Standart uygulamaya bakarsanız, ikinci çözümü seçtiniz: aynı tip parametrelerin alınması.