Extra parameter passing to an overloaded binary operator function

I have a class matrixType that has some overloaded operators (+, -, *, and <<). With a view to having clearly-delineated, perfectly-formatted, four-sided matrices, as shown below:


A = 1 2 3            
    4 5 6				
    7 8 9	

       or	

A + B = 1 2 3
        4 5 6
        7 8 9



and NOT this jagged ones shown below:

A = 1 2 3
4 5 6
7 8 9

     or

A + B = 1 2 3
4 5 6
7 8 9

,

I want a scheme in which the string literals (A, A+B, etc.) could be passed as parameters to the overloaded stream insertion (<<) operator function so that I could use the string’s length to determine how much offset from the display screen’s left to apply to each matrix’s row (by using the setw() function). However, I do know that the << operator is a binary operator, meaning the function cannot take more than two parameters: that is what compounds my problem!

Any insight into this problem or other better schemes I could use will be appreciated.
I think there are some translation errors, I do not understand what you want. I don't see how parameters in the code are related to the alignment.
@geeloso
With a view to having clearly-delineated, perfectly-formatted, four-sided matrices, as shown below:
A = 1 2 3
4 5 6
7 8 9


Could you explain what is the four-sided matrices? In the figure you showed I see a 3 x 3 matrix.
@LB

Thanks for your reply; there are no translation errors anywhere. If you look at the outputs I showed above, you'd notice that the displacement of the first row of each of the matrices from the left pane is a function of the length of the string constant (i.e. A = , A + B =, or even - although not shown - A + B + C = ) of the matrix/matrix operation being considered. Obviously, where the printing of the elements starts for each matrix varies. What I want is a scenario where I can pass a string constant ( "A = ", "A + B = ", ...) to the overloaded << function as a parameter, and use the length of each string constant to format the display of the subsequent rows of the matrix so that the subsequent rows can perfectly align with the first row of the matrix after the '=' sign.

I want to be able to do the output formatting for the display of the matrix elements from within the overloaded << function; not in main function.

Got it? Please ask for more clarification if you need to. Thanks.
A = ...

You've confused people because you are trying to do something weird -- that is, you cannot inspect or modify the way the C++ parser handles whitespace.

It is, unfortunately for your case, entirely up to the user to misformat a matrix.

It is also not possible to simply list numbers without some interleaving operator. Extant matrix classes will do something like:

1
2
3
A = 1, 2, 3,
    4, 5, 6, 
    7, 8, 9;

But again, it is entirely possible for the user to list it some other way.

A use case scenario is to remember that not all matrices are square.
A 3x4 matrix != a 4x3 matrix, for example, but your assignment function seems to want to accept that.

Personally, I would worry less about making C++ look pretty than making things work the C++ way: initialize/assign with an array or iterated sequence.

You can use template powers to make it look fairly natural, for example:
1
2
3
4
5
matrix a = matrix( {
             { 1, 2, 3 }, 
             { 4, 5, 6 },
             { 7, 8, 9 } 
           } );

Eyeball this to help you get started.
http://www.cplusplus.com/forum/general/49079/#msg266703


A + B = ...

I suppose it is possible to do something like that with the latest standard, but don't. C++ isn't a mathematical solver. It is a programming language, and = is an assignment operator, not an equivalence statement. Sorry.

Good luck!
@vlad from moscow:
Could you explain what is the four-sided matrices? In the figure you showed I see a 3 x 3 matrix.

What I meant was that the outline of the printed matrix should form a rectangle; the size of the matrix is irrelevant. If you look at my first post, you would observe that the elements of the first pair of matrices form a rectangle, or roughly, a square(a special form of rectangle); each of which is a four-sided polygon or quadrilateral. Notice the elements of the other pair of matrices do not all align.

@Duoas:
You've confused people because you are trying to do something weird -- that is, you cannot inspect or modify the way the C++ parser handles whitespace.

I disagree with the "weird" characterization of this attempt. All I'm trying to do is format the matrix output so that all the elements align together. I can do it in function main by individually formatting the output with the setw() function depending on what each string literal/constant is, but that would be messy, would waste time and would defeat the adaptive quality a program should have. For instance, in main, the statements

1
2
3
cout<<"A = "<<A;
cout<<"A+B ="<<A+B;
cout<<"A+B+C ="<<A+B+C;

would not produce the perfect rectangle of matrix elements I'm looking for without some formatting in the overloaded << operator function. That's why my first post asked for a means to pass the string literal/constant (preceding the << operator) from main to the function. My prior posts provide more context.

A use case scenario is to remember that not all matrices are square.
A 3x4 matrix != a 4x3 matrix, for example, but your assignment function seems to want to accept that.

I never implied that all matrices are square. Neither did I refer to an assignment function in my earlier posts. True, a 3x4 != 4x3 matrix; but, in maths/linear algebra texts (or even online), both have (roughly) rectangular outlines when their elements(say, integers) are printed.

Personally, I would worry less about making C++ look pretty than making things work the C++ way:

Well, not if you're a student and your TA or professor takes off points for shoddy result presentation! The functionality of my implementations for the +,-,* operator functions is not in question; I have successfully implemented them. However, I think program output is also important for ease of readability and appeal of presentation.

I'm sorry for the verbosity of this post; I'm just trying to make sure I present a clear picture of what I want. If C++ is that hamstrung that my task is outside its realm, then I rest my case. However, I don't think the function-controlled output formatting I want is quixotic or unattainable. I just need a means to pass the string literal/constant from main to the overloaded << function, besides the two parameters the function already takes.

Thanks you both for your responses. So far, this problem is getting the better of me. Alternative schemes are welcome from the forum please.
Last edited on
geeloso wrote:
All I'm trying to do is format the matrix output so that all the elements align together. [...] For instance, in main, the statements

1
2
3
cout<<"A = "<<A;
cout<<"A+B ="<<A+B;
cout<<"A+B+C ="<<A+B+C;

would not produce the perfect rectangle of matrix elements I'm looking for without some formatting in the overloaded << operator function.
THis is why we were confused, we did not catch on that you were talking about output. And in any case, this is user error, you shouldn't try to worry about this. If it really bothers you, just print a new line before each row, rather than after.
@LB:

And in any case, this is user error, you shouldn't try to worry about this.


What do you mean by "user error"?
I have understood nothing.
What is the problem? Where is the code that could be discussed that to see what is the problem? What is there so much bla...bla..bla... instead of a real example?

At least as far as I understood it can be done very simply.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <iostream>
#include <iomanip>
#include <string>
 
int main()
{
    const size_t N = 3;
    int a[N][N] = 
    { 
        { 1, 2, 3 },
        { 4, 5, 6 },
        { 7, 8, 9 }
    };
    
    std::string s = "A = ";
 
    size_t i = 0;
    do
    {
        for ( auto &row : a )
        {
            std::cout << s;
            for ( int x : row ) std::cout << x << ' ';
            std::cout << std::endl;
            s.assign( s.length(), ' ' );
        }
    
        std::cout << std::endl;
        s.assign( "A + B = ");
    } while ( ++i < 2 );
}


Output is

A = 1 2 3 
    4 5 6 
    7 8 9 

A + B = 1 2 3 
        4 5 6 
        7 8 9



EDIT: If you want that some string literal would be passed to overloaded operators then you can define a private member in the class that will contain the indent.And also you can define a public method that will set that indent. For example (without testing):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
class A
{
public:
   A()
   {
      int i = 1;
      for ( auto &row : a )
      {
         for ( int &x : row ) x = i++;
      }
   }

   std::string set_title( const std::string &s )
   {
      std::string t = title;
      title = s;

      return ( t );
   }

   friend std::ostream & operator <<( std::ostream &, const A & );

private:
   enum { N = 3 };
   int a[N][N];
   std::string title;
};


std::ostream & operator <<( std::ostream &os, const A &a )
{
   std::string s = a.title;
   for ( auto &row : a.a )
   {
       os << s;
       for ( int x : row ) os << x << ' ';
       os << std::endl;
       s.assign( s.length(), ' ' );
    }
    
    return ( os << std::endl );
}
Last edited on
@vlad from moscow:

Thanks for your response. You seem to now understand what I have been asking all this while! The example output you showed is exactly what I desire! (with all the matrix elements perfectly aligned). I knew all along that what I wanted to achieve was possible; that I wasn't asking for too much from C++. OK, for starters, I'm still learning C++; hence, I have not fully understood your codes. For instance, the loop conditions in these lines:

1
2
3
4
20  for ( auto &row : a )
            .
            .
23  for ( int x : row )

in main threw me completely off. Please, can you just explain or refer me to related online literature? The for statement format I'm used to is

1
2
for (initial statement; loop condition; update statement)
{...}


I'm still going through your codes and will get back to you soon.
It is so-called the range-based for statement. Your compiler shall support this feature of the C++ 2011 Standard. Otherwise use an ordinary for loop with iterators.
You can check the code I showed on-line at www.ideone.com.
Last edited on
Topic archived. No new replies allowed.