2011-09-16 37 views
6

Bunu şu şekilde yapmaya çalışıyorum:C++ bir dizi için aşırı yüklenme operatörü << nasıl?

template <typename T> 
ostream &operator<<(ostream &os, T &arr) 
{ /*...*/ } 

Ancak T bir diziyi temsil edebilir mi? Bir dizi için << operatörüne aşırı yüklenmek doğru mu?

DÜZENLEME:

Kerrek SB'nin tavsiyesine göre, benim <<:

template <typename T, unsigned int N> 
ostream &operator<<(ostream &os, const T (&arr)[N]) 
{ 
    int i; 
    for(i = 0; i < N; i++) 
     os << arr[i] << " "; 
    os << endl; 
    return os; 
} 

benim uygulamamdır. Derleme hatası aldım.

cevap

7

Bunu yapabilirsiniz:

template <typename T, unsigned int N> 
std::ostream & operator<<(std::ostream & os, const T (&arr)[N]) 
{ 
    // .. 
    return os; 
} 

Bu elbette, derleme zamanı diziler için çalışır. Tstd ad alanında yerleşik bir tür veya bir tür olduğunda bu şablonu başlatmanıza izin verilmediğini unutmayın!

Mümkünse bu satır içi yapmak en iyisidir, çünkü her N için ayrı bir örneğe neden olursunuz. (pretty printer bu bir örnek vardır.) os << "Hello" şimdi iki olası aşırı yükleme vardır, çünkü battaniye şablon bir belirsizliği yaratır, ancak, göreceksiniz

: const char (&)[6] eşleşen şablonu ve (non-şablon) aşırı için her ikisi de aynı dönüşüm sekanslarına sahip olan bozunma-işaretçisi const char *. Aslında o ışığında

template <typename T, unsigned int N, typename CTy, typename CTr> 
typename std::enable_if<!std::is_same<T, char>::value, 
         std::basic_ostream<CTy, CTr> &>::type 
operator<<(std::basic_ostream<CTy, CTr> & os, const T (&arr)[N]) 
{ 
    // .. 
    return os; 
} 

:

#include <ostream> 
#include <type_traits> 

template <typename T, unsigned int N> 
typename std::enable_if<!std::is_same<T, char>::value, std::ostream &>::type 
operator<<(std::ostream & os, const T (&arr)[N]) 
{ 
    // .. 
    return os; 
} 

Aslında, ayrıca basic_ostream parametreleri şablon parametrelerini yapabilirsiniz hatta daha genel olarak: Biz char dizileri için aşırı devre dışı bırakarak bu çözebilirsiniz T kullanıcı tanımlı bir tür olmalı, is_fundamental<T> ile is_same<T, char> ve hatta daha fazla denetim almak için değiştirebilirsiniz (ancak kullanıcılar standart kitaplık türlerinin dizileri için bunu kullanmamalıdır).

+0

sayesinde (vb, öbek üzerinde tahsis, yani diziler), ama Don Aynı zamanda dinamik diziler için çalışacak olan bu yöntemle

int array[10]; //...some code that initializes array, etc. cout << make_pair(array, 10); 

Bir artı: Sonra aşağıdaki gibi kullanabiliriz Inline uygulanmadığı takdirde neden her N için ayrı bir örneğe neden sebep olduğunu anlayamıyorum? – Alcott

+0

Eh, bu bir şablon, bu yüzden her şablon örneği, ikili dosyanızda ayrı bir işlev olarak bitebilir. Eğer satır içi iseniz, fonksiyon çağrısından tamamen kaçınabilirsiniz, ancak bu sonuç derleyiciye bağlıdır. –

+0

anladı.Bu işleçle, 2, 2 tane şablona sahip, ikinci argüm N'yi nasıl belirleyebilirim? Görünüşe göre sadece "cout << ar;" kullanamıyorum, yapabilir miyim? – Alcott

3

bu aşağıdaki gibi bir şey olacaktır yapabileceği bir başka yolu: T bir diziye bir işaretçi alacak

template<typename T> 
ostream& operator<<(ostream &out, const std::pair<T, int>& array) 
{ 
    //...code 
    return out; 
} 

(yani, dizi içine azalacağı işaretçi tipi olacaktır) ve çiftin int bölümü dizinin boyutudur.

+0

Denerim. Teşekkürler – Alcott

+0

Eğer 'T' sizin kullanıcı tanımlı bir tür değilse, emin olamıyorum eğer burada ADL ile sorun olabilir çok hafif bir duygu var. –

+0

"int" gibi bir yapı tipi ile test ettim ... gayet iyi çalışıyor gibiydi ... Bunun neden ADL kuralları ile çatışacağını düşünemiyorum. Eğer bir 'std :: çifti ' nesne varsa, şablon 'nerede' U' 'türde değil türünü, 't' deducing ve' std kullanarak herhangi instantiations :: çifti reddetme kapasitede olmalıdır int' . – Jason

İlgili konular