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 c开发者_运维技巧opied.
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).
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.
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.
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
精彩评论