Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing to a Reference Argument by Value

Consider this simple program:

vector<int> foo = {0, 42, 0, 42, 0, 42};
replace(begin(foo), end(foo), foo.front(), 13);

for(const auto& i : foo) cout << i << '\t';

When I wrote it I expected to get:

13 42 13 42 13 42

But instead I got:

13 42 0 42 0 42

The problem of course is that replace takes in the last 2 parameters by reference. So if either of them happen to be in the range being operated on the results may be unexpected. I can solve this by adding a temporary variable:

vector<int> foo = {0, 42, 0, 42, 0, 42};
const auto temp = foo.front();
replace(begin(foo), end(foo), temp, 13);

for(const auto& i : foo) cout << i << '\t';

I do know that C++11 gave us all kinds of type tools is it possible that I could simply force this value to a non-reference type and pass that inline, without creating the temporary?

like image 664
Jonathan Mee Avatar asked Jun 22 '16 12:06

Jonathan Mee


People also ask

What does it mean to pass a value by reference?

Pass-by-reference means to pass the reference of an argument in the calling function to the corresponding formal parameter of the called function. The called function can modify the value of the argument by using its reference passed in. The following example shows how arguments are passed by reference.

How do you pass by value instead of reference?

Passing a variable The terms “pass by value” and “pass by reference” are used to describe how variables are passed on. To make it short: pass by value means the actual value is passed on. Pass by reference means a number (called an address) is passed on which defines where the value is stored.

What do you mean by argument passing by reference method and by value method?

Pass by value refers to a mechanism of copying the function parameter value to another variable while the pass by reference refers to a mechanism of passing the actual parameters to the function. Thus, this is the main difference between pass by value and pass by reference.


2 Answers

A solution could be as follows (even though you are making a temporary)

template<class T>
void replace_value_of_first(std::vector<T>& v, const T& value)
{
    std::replace(v.begin(), v.end(), T(v.front()), value);
}
like image 83
thorsan Avatar answered Oct 12 '22 13:10

thorsan


You can write a simple function that takes in a reference and returns a value. this will "convert" the reference into a value. This does generate a temporary but it is unnamed and will be destroyed at the end of the full expression. Something like

template<typename T>
T value(const T& ref)
{
    return ref;
}

And then you can use it like

int main()                                                   
{                                                            
    vector<int> foo = {0, 42, 0, 42, 0, 42};
    replace(begin(foo), end(foo), value(foo.front()), 13);

    for(const auto& i : foo) cout << i << '\t';                                      
}

output:

13  42  13  42  13  42

Live Example

like image 33
NathanOliver Avatar answered Oct 12 '22 12:10

NathanOliver