Hi,

after making some adjustmens to my code as recommended, I get those discard qualifiers errors..

//pentathlete.h

#include <iostream>

using namespace std;

template < class T >

class pentathlete {
	protected :
		T comp_res [ 5 ] ;
	public :
	    T sum_res ;
		pentathlete ( ) {
			for ( int i = 0 ; i < 5 ; i ++ ) {
				comp_res [ i ] ;
			}
			sum_res = -1 ;
		}
		pentathlete ( int fir, int sec,
			int thi, int fou, int fif, int fin ) {
			comp_res [ 0 ] = fir ;
			comp_res [ 1 ] = sec ;
			comp_res [ 2 ] = thi ;
			comp_res [ 3 ] = fou ;
			comp_res [ 4 ] = fif ;
			sum_res = fin ;
		}
		void input ( ) {
			for ( int i = 0 ; i < 5 ; i ++ ) {
				cout << "Please enter " << i + 1 
					<< " competition results: " ;
				cin >> comp_res [ i ] ;
				if ( comp_res [ i ] > 100 ) throw "Out of range !\n" ;
				if ( cin . fail ( ) ) throw "Bad input !\n" ;
				cin . clear ( ) ;
			}
		}
		void results ( ) {
			sum_res = 0 ;
			for ( int i = 0; i < 5; i ++ ) {
				sum_res += comp_res [ i ] ;
			}
		}
		void output ( ) { 
			cout << "summarum results: " << sum_res << "\n" ;
		}
};
//main program file

#include <iostream>
#include <C:\MinGW\msys\1.0\home\Owner\pentathlete.h>
//
using namespace std ;
//
class pentathlete_team: public pentathlete < int > {
	public:
		pentathlete_team ( ) : pentathlete < int > ( ) { }
		pentathlete_team ( int fir, int sec,
			int thi, int fou, int fif, int fin ) : pentathlete < int > ( fir, sec, thi, fou, fif, fin ) {
		}
		pentathlete_team operator + ( const pentathlete_team & sec_comp ) const {
				if ( sum_res < 0 ) {
					results ( ) ;
				}
				sec_comp . results ( ) ;
				return pentathlete_team ( 0, 0, 0, 0 ,0, 
					sum_res + sec_comp . sum_res ) ;
			}
};
int main ( ) {
	pentathlete_team p1, p2, p3, result ;
	cout << "First pentathlete results: \n" ;
	try {
		p1 . input ( ) ;
	}
	catch ( const char * error ) {
		cout << "Exception raised: " << error ;
		return 0 ;
	}
	catch ( const char * error ) {
		cout << "Exception raised: " << error ;
		return 0;
	}
	cout << "Second pentathlete results: \n" ;
	try {
		p2 . input ( ) ;
	}
	catch ( const char * error ) {
		cout << "Exception raised: " << error ;
		return 0 ;
	}
	catch ( const char * error ) {
		cout << "Exception raised: " << error ;
		return 0 ;
	}
	cout << "Third pentathlete results: \n" ;
	try {
		p3 . input ( ) ;
		return 0 ;
	}
	catch ( const char * error ) {
		cout << "Exception raised: " << error ;
		return 0 ;
	}
	catch ( const char * error ) {
		cout << "Exception raised: " << error ;
        return 0 ;
	}
	cout << "Summarum results " ;
	result = p1 + p2 + p3 ;
	result . output ( ) ;
	return 0 ;
}
// g++ output

: In member function 'pentathlete_team pentathlete_team::operator+(const pentathlete_team&) const':
:16:16: error: passing 'const pentathlete_team' as 'this' argument of 'void pentathlete<T>::results() [with T = int]' discards qualifiers
:18:26: error: passing 'const pentathlete_team' as 'this' argument of 'void pentathlete<T>::results() [with T = int]' discards qualifiers

if i remove those "const" from operator overloading function - it compiles, but it does not work - operator overloading function does not seem to be initialized somehow..

Let's analyze the error. We know that the error is coming from pentathlete_team::operator+, and that there's an issue in calling the results() member function (which is inherited from pentathlete, though that's irrelevant to the issue).

>passing 'const pentathlete_team' as 'this' argument discards qualifiers
It's pretty obvious that results() doesn't take any parameters, so the only possible way this could be involved is as the object for which you're calling results(). In other words, the sec_comp in sec_comp . results ( ) ; .

sec_comp is passed as a reference to const, so let's take a look at the definition of results and see if it can handle a const object:

void results ( ) {
    sum_res = 0 ;
    for ( int i = 0; i < 5; i ++ ) {
        sum_res += comp_res [ i ] ;
    }
}

Results is not declared as const, and it modifies the non-mutable sum_res data member, so it can't be called on a const object without removing the const qualifier. Clearly the issue is not in results(), but in operator+ not using results() as it was designed. You can remove the constness of sec_comp (not recommended):

pentathlete_team operator + ( pentathlete_team & sec_comp ) {
    if ( sum_res < 0 ) {
        results ( ) ;
    }
    sec_comp . results ( ) ;
    return pentathlete_team ( 0, 0, 0, 0 ,0, 
        sum_res + sec_comp . sum_res ) ;
}

But the problem here is that sec_comp is modified when the semantics of the + operator shouldn't imply that. sec_comp and this (the two operands to operator+) should not be modified by the operation. Instead, you should work with a copy or behave as if a copy was made:

// Naive example
pentathlete_team operator+(const pentathlete_team & sec_comp) const
{
    pentathlete_team lhs(*this);
    pentathlete_team rhs(sec_comp);

    if (lhs.sum_res < 0)
        lhs.results();

    rhs.results();

    return pentathlete_team(0, 0, 0, 0, 0, lhs.sum_res + rhs.sum_res);
}

Edited 5 Years Ago by Narue: n/a

Narue is correct, of course. With, maybe, the additional remark that if you are going to make a copy of the parameters immediately as you enter the function, you are better off passing-by-value instead, you get a local copy, and you allow the compiler more opportunity for optimizations. Furthermore, operators like + should be implemented as friend functions. So, you would get:

friend
pentathlete_team operator+(pentathlete_team lhs, pentathlete_team rhs) 
{
    if (lhs.sum_res < 0)
        lhs.results();

    rhs.results();

    return pentathlete_team(0, 0, 0, 0, 0, lhs.sum_res + rhs.sum_res);
}

On a design perspective, you are missing a very nice opportunity here. You, correctly, made the data members of the pentathlete protected-access. This means, you have control over all modifications to those values. So, a function like results(), whose purpose is to make sure that the sum_res corresponds to the stores result array values, should not need to be called unless you are modifying the comp_res array. Since you control all access to comp_res, you can easily call results() every time the values were updated, ensuring that sum_res' value is always in sync with comp_res' values. If you do that, you will have no reason to call results() in your operator+, thus eliminating the original error, reducing the amount of code, and getting a more robust design. This is why const-correctness is nice, it tells you where you have made design mistakes that you could significantly improve on.

Let's analyze the error. We know that the error is coming from pentathlete_team::operator+, and that there's an issue in calling the results() member function (which is inherited from pentathlete, though that's irrelevant to the issue).

>passing 'const pentathlete_team' as 'this' argument discards qualifiers
It's pretty obvious that results() doesn't take any parameters, so the only possible way this could be involved is as the object for which you're calling results(). In other words, the sec_comp in sec_comp . results ( ) ; .

sec_comp is passed as a reference to const, so let's take a look at the definition of results and see if it can handle a const object:

void results ( ) {
    sum_res = 0 ;
    for ( int i = 0; i < 5; i ++ ) {
        sum_res += comp_res [ i ] ;
    }
}

Results is not declared as const, and it modifies the non-mutable sum_res data member, so it can't be called on a const object without removing the const qualifier. Clearly the issue is not in results(), but in operator+ not using results() as it was designed. You can remove the constness of sec_comp (not recommended):

pentathlete_team operator + ( pentathlete_team & sec_comp ) {
    if ( sum_res < 0 ) {
        results ( ) ;
    }
    sec_comp . results ( ) ;
    return pentathlete_team ( 0, 0, 0, 0 ,0, 
        sum_res + sec_comp . sum_res ) ;
}

But the problem here is that sec_comp is modified when the semantics of the + operator shouldn't imply that. sec_comp and this (the two operands to operator+) should not be modified by the operation. Instead, you should work with a copy or behave as if a copy was made:

// Naive example
pentathlete_team operator+(const pentathlete_team & sec_comp) const
{
    pentathlete_team lhs(*this);
    pentathlete_team rhs(sec_comp);

    if (lhs.sum_res < 0)
        lhs.results();

    rhs.results();

    return pentathlete_team(0, 0, 0, 0, 0, lhs.sum_res + rhs.sum_res);
}

thank you for your answer, but it did not help me. If i use your native example as it is written, i get the same results as removing "const". And that result that i get is nothing. After inputing everything, the program just shutdowns and does not show any output. And that is not all ! If i write some simple cout << "TEST" ; into the beginning of operator+ function - i get nothing ! so it seems that operator+ function is not being loaded/initialized or whatever (i do not know how to correctly call :S)

Narue is correct, of course. With, maybe, the additional remark that if you are going to make a copy of the parameters immediately as you enter the function, you are better off passing-by-value instead, you get a local copy, and you allow the compiler more opportunity for optimizations. Furthermore, operators like + should be implemented as friend functions. So, you would get:

friend
pentathlete_team operator+(pentathlete_team lhs, pentathlete_team rhs) 
{
    if (lhs.sum_res < 0)
        lhs.results();

    rhs.results();

    return pentathlete_team(0, 0, 0, 0, 0, lhs.sum_res + rhs.sum_res);
}

On a design perspective, you are missing a very nice opportunity here. You, correctly, made the data members of the pentathlete protected-access. This means, you have control over all modifications to those values. So, a function like results(), whose purpose is to make sure that the sum_res corresponds to the stores result array values, should not need to be called unless you are modifying the comp_res array. Since you control all access to comp_res, you can easily call results() every time the values were updated, ensuring that sum_res' value is always in sync with comp_res' values. If you do that, you will have no reason to call results() in your operator+, thus eliminating the original error, reducing the amount of code, and getting a more robust design. This is why const-correctness is nice, it tells you where you have made design mistakes that you could significantly improve on.

Thank you for your answer too ! i will try to make design changes, while doing that i tryed your code - same no output as with narue's code, and as with just "const" removed from that function...

You should post your code that uses the + operator. The problem is possibly (or probably) there.

Compiles, but no output:

/*friend*/ pentathlete_team operator + ( /*pentathlete_team lhs, pentathlete_team rhs ) const */pentathlete_team /*&*/ sec_comp ) /*const*/ {
			cout << "TEST" ;
			//pentathlete_team lhs ( * this ) ;
			//pentathlete_team rhs ( sec_comp ) ;
			return pentathlete_team ( 0, 0, 0, 0 ,0, 
				sum_res + sec_comp . sum_res ) ;
		}

Compiles, but no output:

friend pentathlete_team operator + ( pentathlete_team lhs, pentathlete_team rhs ) /*const pentathlete_team & sec_comp ) const*/ {
			cout << "TEST" ;
			//pentathlete_team lhs ( * this ) ;
			//pentathlete_team rhs ( sec_comp ) ;
			return pentathlete_team ( 0, 0, 0, 0 ,0, 
				lhs . sum_res + rhs . sum_res ) ;
		}

Compiles, but no output:

/*friend*/ pentathlete_team operator + ( /*pentathlete_team lhs, pentathlete_team rhs ) */ const pentathlete_team & sec_comp ) const {
			cout << "TEST" ;
			//pentathlete_team lhs ( * this ) ;
			//pentathlete_team rhs ( sec_comp ) ;
			return pentathlete_team ( 0, 0, 0, 0 ,0, 
				sum_res + sec_comp . sum_res ) ;
		}

does not compile and gives errors:

friend pentathlete_team operator + ( /*pentathlete_team lhs, pentathlete_team rhs ) */ const pentathlete_team & sec_comp ) const {
			cout << "TEST" ;
			//pentathlete_team lhs ( * this ) ;
			//pentathlete_team rhs ( sec_comp ) ;
			return pentathlete_team ( 0, 0, 0, 0 ,0, 
				sum_res + sec_comp . sum_res ) ;
		}

errors of the above code:

//g++ output:

.cpp:14:126: error: non-member function 'pentathlete_team operator+(const pentathlete_team&)' cannot have cv-qualifier
\...\pentathlete.h: In function 'pentathlete_team operator+(const pentathlete_team&)':
\...\pentathlete.h:12:5: error: invalid use of non-static data member 'pentathlete<int>::sum_res'
.cpp:19:5: error: from this location
.cpp: In function 'int main()':
.cpp:62:16: error: no match for 'operator+' in 'p1 + p2'
.cpp:14:27: note: candidate is: pentathlete_team operator+(const pentathlete_team&)

oh, and as i changed some things, the line counting of the first post changed, so here it is:

//pentathlete.h

#include <iostream>

using namespace std;

template < class T >

class pentathlete {
	protected :
		T comp_res [ 5 ] ;
		T sum_res ;
	public :
	    //T sum_res ;
		pentathlete ( ) {
			for ( T i = 0 ; i < 5 ; i ++ ) {
				comp_res [ i ] ;
			}
			sum_res = 0 ;
		}
		pentathlete ( T fir, T sec,
			T thi, T fou, T fif, T fin ) {
			comp_res [ 0 ] = fir ;
			comp_res [ 1 ] = sec ;
			comp_res [ 2 ] = thi ;
			comp_res [ 3 ] = fou ;
			comp_res [ 4 ] = fif ;
			sum_res = fin ;
			results ( ) ;
		}
		void input ( ) {
			for ( T i = 0 ; i < 5 ; i ++ ) {
				cout << "Please enter " << i + 1 
					<< " competition results: " ;
				cin >> comp_res [ i ] ;
				if ( comp_res [ i ] > 100 ) throw "Out of range !\n" ;
				if ( cin . fail ( ) ) throw "Bad input !\n" ;
				cin . clear ( ) ;
			}
			results ( ) ;
		}
		void results ( ) {
			cout << "test" ;
			sum_res = 0 ;
			for ( T i = 0 ; i < 5 ; i ++ ) {
				sum_res += comp_res [ i ] ;
			}
		}
		void output ( ) { 
			cout << "summarum results: " << sum_res << "\n" ;
		}
};
//main program file

#include <iostream>
#include <C:\MinGW\msys\1.0\home\Owner\pentathlete.h>
//
using namespace std ;
//
class pentathlete_team: public pentathlete < int > {
	public:
		pentathlete_team ( ) : pentathlete < int > ( ) { }
		pentathlete_team ( int fir, int sec,
			int thi, int fou, int fif, int fin ) : pentathlete < int > ( fir, sec, thi, fou, fif, fin ) {
		}
		/*friend*/ pentathlete_team operator + ( /*pentathlete_team lhs, pentathlete_team rhs ) */ const pentathlete_team & sec_comp ) const {
			cout << "TEST" ;
			//pentathlete_team lhs ( * this ) ;
			//pentathlete_team rhs ( sec_comp ) ;
			return pentathlete_team ( 0, 0, 0, 0 ,0, 
				sum_res + sec_comp . sum_res ) ;
		}
};
int main ( ) {
	pentathlete_team p1, p2, p3, result ;
	cout << "First pentathlete results: \n" ;
	try {
		p1 . input ( ) ;
	}
	catch ( const char * error ) {
		cout << "Exception raised: " << error ;
		return 0 ;
	}
	catch ( const char * error ) {
		cout << "Exception raised: " << error ;
		return 0 ;
	}
	cout << "Second pentathlete results: \n" ;
	try {
		p2 . input ( ) ;
	}
	catch ( const char * error ) {
		cout << "Exception raised: " << error ;
		return 0 ;
	}
	catch ( const char * error ) {
		cout << "Exception raised: " << error ;
		return 0 ;
	}
	cout << "Third pentathlete results: \n" ;
	try {
		p3 . input ( ) ;
		return 0 ;
	}
	catch ( const char * error ) {
		cout << "Exception raised: " << error ;
		return 0 ;
	}
	catch ( const char * error ) {
		cout << "Exception raised: " << error ;
        return 0 ;
	}
	cout << "Summarum results " ;
	result = p1 + p2 + p3 ;
	result . output ( ) ;
	return 0 ;
}

Edited 5 Years Ago by n0de: n/a

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