Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Function Parameters as Const Reference

Tags:

c++

Is there any reason not to send a parameter as a const & , instead of by value, when it will not be changed and no copy will be made? My understanding is that a const by value parameter is the same as without the const (and won't overload each other) so it will still be copied.

I know it's best for large objects to send by const &, but I don't know where the line for this is. Or if even small parameters should be sent by value if they won't be changed or copied.

Note:: I tried searching for this but the topic is fairly vague so I did not find any good answers, I apologize if this has been answered already (found many questions about when to use const when to use const & but not about the advantages of value vs const & for objects not obviously large).

like image 450
Stu Avatar asked Jul 22 '11 15:07

Stu


People also ask

What is the benefit of declaring the parameter as a const reference?

The important difference is that when passing by const reference, no new object is created. In the function body, the parameter is effectively an alias for the object passed in. Because the reference is a const reference the function body cannot directly change the value of that object.

Why should we use const references for function parameters rather than pass by value?

Passing a parameter by const reference should be chosen where the semantics of references are actually required, or as a performance improvement only if the cost of potential aliasing would be outweighed by the expense of copying the parameter. At times, copying your parameters can also give you locality benefits.

When should you use a const reference parameter?

Pass Using Const Reference in C++ Now, we can use the const reference when we do not want any memory waste and do not change the variable's value. The above code will throw a compile error as num = num +10 is passed as a const reference.

How do you pass a constant reference?

When you pass by const reference, you take the argument in by reference (avoiding making any copies of it), but cannot make any changes to the original object (much as would happen when you would take the parameters in by value).


3 Answers

There's generally nothing wrong with passing read-only arguments as const-references, and for any sort of heavy-weight class that's surely the most efficient way to do it.

You might want to consider passing primitive types by copy, though, because there making the reference might actually incur more cost than just copying (e.g. copying would just fit into one register, while a reference might be implemented with a pointer, etc.).

Also, you can probably pass std::shared_ptr and iterators by value, they're made for that.

As for passing by const-value, that's an implementation detail. Use it like this:

// Declaration:
int foo(int n, double d); // No "const"! Constness is not part of the interface.

// Definition
int foo(int n, const double d) // implementation detail
{
  while (n--) { if (d > n) return n; }
}

In the implementation, you may or may not choose to use the argument variables directly and modify them (like n), or you may choose to treat them as read-only (like d), and you declare the arguments appropriately.

like image 136
Kerrek SB Avatar answered Oct 18 '22 23:10

Kerrek SB


As a rule of thumb, you should pass primitive types such as pointers, int, bool, float, double by (non-const) value, and object types such as std::string, std::vector and custom classes by (const) reference. As an exception to this rule, there are light-weight classes that are specifically designed to be passed by value, such as smart pointers.

Passing a value by const value, e.g. void foo(const double bar), makes no sense -- why shouldn't foo be allowed to modify its copy of bar? Declaring the parameter as const has no use here.

Passing primitives by reference makes little sense as well. Behind the scenes, when a parameter is passed by reference, a pointer is passed by value. Copying a pointer is usually just as expensive as copying a primitive type (such as int), and parameters of type const int& look pretty weird to most C++ programmers.

like image 43
Ferdinand Beyer Avatar answered Oct 18 '22 22:10

Ferdinand Beyer


Unless an interface demands it, primitives should be passed by value. Otherwise, const& is a better practice.

boost::is_fundamental

Identifying primitive types in templates

like image 3
Tom Kerr Avatar answered Oct 18 '22 21:10

Tom Kerr