Reputation: 325
I am a bit confused about one of the examples in my textbook. When the string is created, it is created as type string
. However, when the same string is passed into a function, the function parameters are of const string
and not string
.
Here's the part of the code:
int main()
{
string str;
cout << "blah blah..";
getline(cin, str);
if (is_pal(str))
//...
}
bool is_pal(const string& s)
{
//...
}
Why is the function parameter const string& s
instead of just string& s
? I've read through my textbook but can't seem to find any explanation for this.
Upvotes: 6
Views: 7673
Reputation: 145249
Re
” why is the function parameter
const string& s
instead of juststring& s
?
A main reason is that the latter can't bind to string literal or to an ordinary function result or result of string operators such as +
, called an “rvalue”.
Well at least in standard C++, but Visual C++ allows that as an unfortunate language extension.
Another reason usually is that the author of the function thought it could be more useful when it promises to not modify its argument. Or at least, that that would make it easier to reason about code using it.
Example:
// To see the problem also with Visual C++, use that compiler's /Za option.
#include <iostream>
#include <string>
using namespace std;
void goodwrite( const string& s ) { cout << s << '\n'; }
void badwrite( string& s ) { cout << s << '\n'; }
auto main() -> int
{
// Good:
goodwrite( "The answer is " + to_string( 6*7 ) + "." );
//! Uh oh, doesn't compile with standard C++:
badwrite( "The answer is " + to_string( 6*7 ) + "." );
}
Upvotes: 4
Reputation: 11504
TL;DR: to ensure that object isn't modified in function and to save one copy operation.
Only const
methods may be called for const
objects, and that methods couldn't alter state of an object:
class A {
int i = 10;
mutable int j = 10; // Explicitly allowed to change even for const objects
public:
void f() { ++i; } // OK: non-const function changes object
void g() const { ++i; } // Error: const function changes object
int h() const { return i; } // OK: const function doesn't change object
int s() const { return ++j; } // OK: const function changes mutable field
};
void foo(const A& a) {
a.f(); // Error: only const methods are allowed
a.g(); a.h(); a.j(); // OK
}
As you can see, there is no clean way to modify field i
from function foo
, but you can read A
fields with h()
and s()
methods.
You can also ensure that your local object isn't modified by callee function by passing copy to it:
void foo(A a);
bool is_pal(std::string s);
But copying may be expensive, so you have to pass it by reference:
void foo(A& a);
bool is_pal(std::string& s);
And to ensure that object will have same state it had before calling your function you have to add const
qualifier to it. This idiom is explained in Scott Meyers’ book, Effective C++, Third Edition, "Item 20: Prefer pass-by-reference-to-const to pass-by-value."
Upvotes: 0
Reputation: 70392
When a function uses const
on its argument, it typically means the function will not alter the argument.
When you are writing your own functions, you should determine if the function intends to modify the argument or not, and use or not use const
accordingly.
Likewise, when you are using functions that someone else has written, pay attention to whether or not the function intends to modify your object or not. This is made known to you if the function accepts a non-const
reference.
void foo_will_not_modify (const std::string &x); // const ref - won't modify
void bar_will_not_modify (std::string x); // copy - won't modify
void baz_will_modify (std::string &x); // reference - can modify
Upvotes: 4
Reputation: 76
You can do this without the "const" keyword.
It is usually the best practice to use "const" keyword for parameters if your function is not modifying it. So, by mistake if you try to modify the parameters, it will shoe error.
It's just the best coding practice, I would suggest you also do the same if the function is not modifying the parameters.
Upvotes: 0
Reputation: 119134
Objects that may be expensive to copy, such as std::string
, are very often passed by const lvalue reference in C++. This is a very common idiom; you will see it everywhere. A const lvalue reference can bind to both lvalues and rvalues without making any copies, so this is an efficient way to pass strings to functions that will not modify them.
Upvotes: 9
Reputation: 311188
Passing a const
reference means that the function will treat the argument as a constant, and will not modify it by any way. This allows calling this function with const values - either ones explicitly defined as const
s, or implicit constants, such as string literals.
Upvotes: 0