ruisen
ruisen

Reputation: 325

Why is a string passed as const string in a function parameter

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

Answers (6)

Cheers and hth. - Alf
Cheers and hth. - Alf

Reputation: 145249

Re

why is the function parameter const string& s instead of just string& 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

myaut
myaut

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

jxh
jxh

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

Akash
Akash

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

Brian Bi
Brian Bi

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

Mureinik
Mureinik

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 consts, or implicit constants, such as string literals.

Upvotes: 0

Related Questions