hi, i'm having trouble compiling this code:
SparseMatrix.h:

#ifndef SPARSE_MATRIX
#define SPARSE_MATRIX
#include <ostream>

class SparseMatrix {
//class data
...
SparseMatrix operator+(const SparseMatrix& rhs) const;
SparseMatrix operator*(const SparseMatrix& rhs) const;
};

ostream& operator<<(ostream& out, SparseMatrix& rhs);
#endif

SparseMatrix.cpp:

#include "SparseMatrix.h"
ostream& operator<<(ostream& out, SparseMatrix& rhs) {
...
}
SparseMatrix SparseMatrix::operator+(const SparseMatrix& rhs) const {
...
}
SparseMatrix SparseMatrix::operator*(const SparseMatrix& rhs) const {
...
}

and main.cpp:

#include "SparseMatrix.h"
#include <iostream>

int main() {
    const SparseMatrix sm(3, 4); 
    const SparseMatrix sm2(4, 5); 
    sm.setElement(1, 2, 5); 
    sm2.setElement(3, 1, 5); 

    cout << sm << endl;
    cout << sm2 << endl;
    SparseMatrix m = sm+sm2;
    cout << m << endl;

    return 0;
}

But the compilation of main.cpp just gives me a long list of STL errors.
main.cpp:7: error: passing ‘const SparseMatrix’ as ‘this’ argument of ‘void SparseMatrix::setElement(int, int, int)’ discards qualifiers
main.cpp:8: error: passing ‘const SparseMatrix’ as ‘this’ argument of ‘void SparseMatrix::setElement(int, int, int)’ discards qualifiers
main.cpp:10: error: no match for ‘operator<<’ in ‘std::cout << sm’
/usr/include/c++/4.4/ostream:108: note: candidates are: bla bla bla
and
SparseMatrix.h:38: note: std::ostream& operator<<(std::ostream&, SparseMatrix&)
main.cpp:11: error: no match for ‘operator<<’ in ‘std::cout << sm2’
/usr/include/c++/4.4/ostream:108: note: candidates are: bla bla bla
What is wrong here?
Thanks!

Your objects are set to const . You can't hope to accomplish anything if they are constants. Start by making the objects themselves non-const then go from there. You can use const for arguments/parameters/methods without having the original variables/objects set as const themselves.

Edited 6 Years Ago by Fbody: corrected tagging error

For your overloaded << operator it would have to be defined as ostream& operator<<(ostream& out, const SparseMatrix& rhs); otherwise the compiler is unsure whether the method will try to modify the const object or not.

Edited 6 Years Ago by jonsca: n/a

Thanks for the comments!
The const was missing in both places because i tried with and without it. Still not working, now it's a linker error:
/tmp/ccvcPoiE.o: In function `main':
main.cpp: (.text+0x9e): undefined reference to `operator<<(std::basic_ostream<char, std::char_traits<char> >&, SparseMatrix const&)'
main.cpp: (.text+0xc1): undefined reference to `operator<<(std::basic_ostream<char, std::char_traits<char> >&, SparseMatrix const&)'
main.cpp: (.text+0xea): undefined reference to `SparseMatrix::operator+(SparseMatrix const&) const'
main.cpp: (.text+0x100): undefined reference to `operator<<(std::basic_ostream<char, std::char_traits<char> >&, SparseMatrix const&)'
collect2: ld returned 1 exit status

Edited 6 Years Ago by invinate: n/a

You haven't selected a namespace, so the compiler doesn't recognize the object cout.

/* you will need to select one of these code blocks */
/* option 1 */
using namespace std;

/* option 2 */
using std::cout;
/* there may be others, your code snippets only indicate cout though */

You can also replace all instances of cout with std::cout

Edited 6 Years Ago by Fbody: n/a

using namespace std; is in all 3 files now, but that doesn't help. same errors

Try prepending "friend" to your declaration (not definition) of this << method: friend ostream& operator<<(ostream& out, const SparseMatrix& rhs);

SparseMatrix.h:38: error: ‘friend’ used outside of class
and the same linker error as above when i put operator<< inside the class.

That's why I said to put it in the declaration (up in the header in the class SparseMatrix{//declarations go here}; It does not go in front of the definition (where you write out the procedures of the method).

Like I said, I also tried putting the declaration "friend openrator<<" inside the class and got the above linker errors.

Like I said, I also tried putting the declaration "friend openrator<<" inside the class and got the above linker errors.

Use it only inside the class, not in the external definition. There should only be one (1) use of it, and that's inside your class declaration.

no, i removed the const in main right after you pointed it out, so it's without the const. but it compiles ok, it just doesn't link for some reason

Are you compiling both the *.cpp files as part of your project, or just the file that contains the main()? If it's not linking, it usually means its looking for a function's implementation (which an operator overload is) but it can't find it.

Yes, I compile like this:
g++ -o sm main.cpp SparseMatrix.cpp -Wall
/tmp/ccNwb3iE.o: In function `main':
main.cpp: (.text+0x9e): undefined reference to `operator<<(std::basic_ostream<char, std::char_traits<char> >&, SparseMatrix const&)'
main.cpp: (.text+0xc1): undefined reference to `operator<<(std::basic_ostream<char, std::char_traits<char> >&, SparseMatrix const&)'
main.cpp: (.text+0x100): undefined reference to `operator<<(std::basic_ostream<char, std::char_traits<char> >&, SparseMatrix const&)'
collect2: ld returned 1 exit status

Edited 6 Years Ago by invinate: n/a

You may want to post the most current version of your code so that we know what we're dealing with. Without it, we're flying blind. It's obviously an issue with either the declaration or definition of SparseMatrix::operator<< .

Have you tried moving its declaration inside your class definition? Are you doing a #include <iostream> in your header/implementation files?

Edited 6 Years Ago by Fbody: n/a

Finally, I found my error. The definition of operator<< was without const for the second argument! Now it links and runs. Thanks Fbody and jonsca for your help!

This question has already been answered. Start a new discussion instead.