Why use a copy of an object as an argument to a function? Why is const ref not the default parameter way?


Birgersp

As much as I love C++ programming, I really don't have one thing. In my opinion, the most common way to program functions is like this:

some_function(a variable)
    do something according to the data in the variable

example:

bool match_name(const std::string& name)
{
    return this->name == name;
}

I find myself using const ref in 90% of all function parameters in my code (maybe I'm doing it wrong).

My question is: why is the copy of the variable the "default" type of the parameter? Why is const ref not the default value?

Why not? :

void my_function(My_type object)      // <- const ref

void my_function(ref My_type object)  // <- ref (mutable)

void my_function(copy My_type object) // <- copy
Nikos C.

C++ wants to be compatible with C, and since C uses value semantics by default, so does C++. Getting built-in types by value and other types by reference would be very inconsistent.

However, passing by reference is not always better. Pointer indirection caused by references often makes it harder for the compiler to optimize code generation. Passing types by value is still better than passing by ref in many cases. It depends on the type. Pointer-by-reference indirection can result in memory reads, while pass-by-value allows objects to be passed in CPU registers. For example, a type like this:

class Point {
public:
    /* functions */
private:
    int x;
    int y;
};

Should always be passed by value. It's just two integers. References can cause unnecessary memory reads to get values.

Also, sometimes you want to pass by value even if you can't register the type. For example, so-called "receiver functions" that need to store the passed value perform better when using the value due to move semantics. The main example is constructros and setters:

void SomeClass::setString(std::string s)
{
    this->s_ = std::move(s);
}

Passing by reference in this case may result in an extra copy. You can read more online. A good starting point is this question:

Gone are the days of passing const std::string& as arguments?

Related


Why use function parameter 'foo' in this way: *(&foo)?

Roughness The code snippet in Linux kernel 0.12 uses the following function parameters: int do_signal(int signr, int eax /* other parameters... */) { /* ... */ *(&eax) = -EINTR; /* ... */ } The purpose of this code is to put -EINTR in the memory

Why use function parameter 'foo' in this way: *(&foo)?

Roughness The code snippet in Linux kernel 0.12 uses the following function parameters: int do_signal(int signr, int eax /* other parameters... */) { /* ... */ *(&eax) = -EINTR; /* ... */ } The purpose of this code is to put -EINTR in the memory

Why use function parameter 'foo' in this way: *(&foo)?

Roughness The code snippet in Linux kernel 0.12 uses the following function parameters: int do_signal(int signr, int eax /* other parameters... */) { /* ... */ *(&eax) = -EINTR; /* ... */ } The purpose of this code is to put -EINTR in the memory

Why use function parameter 'foo' in this way: *(&foo)?

Roughness The code snippet in Linux kernel 0.12 uses the following function parameters: int do_signal(int signr, int eax /* other parameters... */) { /* ... */ *(&eax) = -EINTR; /* ... */ } The purpose of this code is to put -EINTR in the memory

Why not remove the copy as a function parameter

Matt Spicer I have the following code #include <cstdlib> #include <vector> #include <chrono> #include <iostream> static const uint64_t BENCHMARK_RUNS(1000000); std::vector<float> vec_mul_no_ref(const std::vector<float> x, co

Why not remove the copy as a function parameter

Matt Spicer I have the following code #include <cstdlib> #include <vector> #include <chrono> #include <iostream> static const uint64_t BENCHMARK_RUNS(1000000); std::vector<float> vec_mul_no_ref(const std::vector<float> x, co

Why not remove the copy as a function parameter

Matt Spicer I have the following code #include <cstdlib> #include <vector> #include <chrono> #include <iostream> static const uint64_t BENCHMARK_RUNS(1000000); std::vector<float> vec_mul_no_ref(const std::vector<float> x, co

Why not remove the copy as a function parameter

Matt Spicer I have the following code #include <cstdlib> #include <vector> #include <chrono> #include <iostream> static const uint64_t BENCHMARK_RUNS(1000000); std::vector<float> vec_mul_no_ref(const std::vector<float> x, co

Why not remove the copy as a function parameter

Matt Spicer I have the following code #include <cstdlib> #include <vector> #include <chrono> #include <iostream> static const uint64_t BENCHMARK_RUNS(1000000); std::vector<float> vec_mul_no_ref(const std::vector<float> x, co

Why not remove the copy as a function parameter

Matt Spicer I have the following code #include <cstdlib> #include <vector> #include <chrono> #include <iostream> static const uint64_t BENCHMARK_RUNS(1000000); std::vector<float> vec_mul_no_ref(const std::vector<float> x, co

Why not remove the copy as a function parameter

Matt Spicer I have the following code #include <cstdlib> #include <vector> #include <chrono> #include <iostream> static const uint64_t BENCHMARK_RUNS(1000000); std::vector<float> vec_mul_no_ref(const std::vector<float> x, co

Why default char* in parameter must be const?

Huon Kaw class MyString { private: char *m_pchString; int m_nLength; public: MyString(char* pchString="0") { //problem on this parameter m_nLength = strlen(pchString)+1; m_pchString = new char[m_nLength]; strncpy(m_pchS

Why default char* in parameter must be const?

Huon Kaw class MyString { private: char *m_pchString; int m_nLength; public: MyString(char* pchString="0") { //problem on this parameter m_nLength = strlen(pchString)+1; m_pchString = new char[m_nLength]; strncpy(m_pchS

Why default char* in parameter must be const?

Huon Kaw class MyString { private: char *m_pchString; int m_nLength; public: MyString(char* pchString="0") { //problem on this parameter m_nLength = strlen(pchString)+1; m_pchString = new char[m_nLength]; strncpy(m_pchS

Why use ref as array parameter in C#?

Tyler Durden I read the page on using ref outgoing arrays (C# Programming Guide) and wondered why an array parameter needs to be defined as a ref parameter when the array parameter is already a reference type. Won't changes in the callee function be reflected

Why pass string as const string in function parameter

Risen I'm a little confused about an example in the textbook. After the string is created, it will be created as string type. However, when passing the same string to a function, the function parameter is a const string, not a string. Here is part of the code: