Saya menulis perpustakaan matriks kecil di C ++ untuk operasi matriks. Namun kompiler saya mengeluh, di mana sebelumnya tidak. Kode ini dibiarkan di rak selama 6 bulan dan di antaranya saya memutakhirkan komputer saya dari debian etch ke lenny (g ++ (Debian 4.3.2-1.1) 4.3.2) namun saya memiliki masalah yang sama pada sistem Ubuntu dengan g ++ yang sama .
Inilah bagian yang relevan dari kelas matriks saya:
namespace Math
{
class Matrix
{
public:
[...]
friend std::ostream& operator<< (std::ostream& stream, const Matrix& matrix);
}
}
Dan "implementasi":
using namespace Math;
std::ostream& Matrix::operator <<(std::ostream& stream, const Matrix& matrix) {
[...]
}
Ini adalah kesalahan yang diberikan oleh kompiler:
matrix.cpp: 459: error: 'std :: ostream & Math :: Matrix :: operator << (std :: ostream &, const Math :: Matrix &)' harus mengambil tepat satu argumen
Saya agak bingung dengan kesalahan ini, tapi sekali lagi C + + saya sudah agak berkarat setelah melakukan banyak Jawa 6 bulan itu. :-)
sumber
operator<<
harus ada di namespaceMath
? Tampaknya itu harus di namespace global. Saya setuju bahwa kompiler saya ingin berada di namespace ofMath
, tapi itu tidak masuk akal bagi saya.Hanya memberi tahu Anda tentang satu kemungkinan lain: Saya suka menggunakan definisi teman untuk itu:
Fungsi ini akan secara otomatis ditargetkan ke namespace sekitarnya
Math
(meskipun definisinya muncul dalam lingkup kelas itu) tetapi tidak akan terlihat kecuali jika Anda memanggil operator << dengan objek Matrix yang akan membuat pencarian bergantung argumen menemukan definisi operator. Itu kadang-kadang dapat membantu dengan panggilan ambigu, karena tidak terlihat untuk tipe argumen selain Matrix. Saat menulis definisi, Anda juga dapat merujuk langsung ke nama yang didefinisikan dalam Matrix dan Matrix itu sendiri, tanpa memenuhi syarat nama dengan beberapa awalan yang mungkin panjang dan menyediakan parameter templat sepertiMath::Matrix<TypeA, N>
.sumber
Untuk menambahkan jawaban Mehrdad,
Dalam implementasi Anda
sumber
Dengan asumsi bahwa kita sedang berbicara tentang overloading
operator <<
untuk semua kelas yang berasal daristd::ostream
untuk menanganiMatrix
kelas (dan bukan overloading<<
untukMatrix
kelas), lebih masuk akal untuk mendeklarasikan fungsi overload di luar namespace Math di header.Gunakan fungsi teman hanya jika fungsi tidak dapat dicapai melalui antarmuka publik.
Matrix.h
Perhatikan bahwa kelebihan operator dinyatakan di luar namespace.
Matrix.cpp
Di sisi lain, jika fungsi kelebihan Anda perlu dijadikan teman, maka perlu akses ke anggota pribadi dan yang dilindungi.
Math.h
Anda harus menyertakan definisi fungsi dengan blok namespace bukan hanya
using namespace Math;
.Matrix.cpp
sumber
Di C ++ 14 Anda dapat menggunakan templat berikut untuk mencetak objek yang memiliki T :: print (std :: ostream &) const; anggota.
Dalam C ++ 20 Konsep dapat digunakan.
sumber
std::ostream&
, karena ini adalah tipe pengembaliannya?