3.3 Why do I get a message about discarding
qualifiers?
The message
In some-function-name, passing const some-type-name …
discards qualifiers
occurs when you try to pass a const object to a function that might
try to change the object’s value. For example, if you have a
class C:
class
C
{
public
:
C
();
int
foo
();
void
bar
(
std
::
string
&
s
);
⋮
}
and you try to compile the following code:
void
baz
(
const
C
&
c1
,
C
&
c2
,
const
std
::
string
&
str
)
{
int
i
=
c1
.
foo
();
//
error
!
int
j
=
c2
.
foo
();
c2
.
bar
(
str
);
//
error
!
⋮
then a C++ compiler should flag the 1st and 3rd line indicated
above. The g++ compiler will say something along the lines of
In
function
’
void
baz
(
const
C
\&,
C
\&,
const
std
::
string
\&)’:
passing
’
const
C
’
as
’
this
’
argument
of
’
int
C
::
foo
()’
discards
qualifiers
In
function
’
void
baz
(
const
C
\&,
C
\&,
const
std
::
string
\&)’:
passing
’
const
std
::
string
’
as
argument
1
of
’
void
C
::
bar
(
std
::
string
\&)’
discards
qualifiers
The first message complains that you have passed
a const object as the left-hand parameter (implicitly named this) to the function foo, which has not promised to leave
that parameter unchanged. You have, in effect, tried to discard the
"qualifier" (the word "const")
in the const C& datatype.
The second message makes a similar complaint about the string
parameter being passed to bar.
Again, the object being passed is marked as const, but the declaration of bar suggests that bar is allowed to change the string it
receives as a parameter. To get rid of this message, you must
examine what it is you are trying to do and determine whether:
- The declarations of the functions you are
trying to call are incorrect. Perhaps foo and bar really should promise to leave those parameters
unchanged. I.e., perhaps they should have been declared like this:
class C {
public:
C();
int foo () const;
void bar (const std::string& s);
⋮
}
- or, perhaps the application code is declaring
things as const that it really
does want to change:
void baz (C& c1, C& c2, std::string& str)
{
int i = c1.foo();
int j = c2.foo();
c2.bar(str);
⋮
- or, perhaps the application really is not
supposed to change those parameters, and you will need to find some
other way to accomplish what you need to do. For example,
void baz (const C& c1, C& c2, const std::string& str)
{
C c1Copy = c1;
int i = c1Copy.foo();
int j = c2.foo();
⋮
