Passing a parameter by a c++reference

How do I pass a function a parameter by reference with a default value?

void func(int &i)

void func2(set<int> &s)

And at the same time be able to call these functions without arguments, so that the variable i is assigned a default value, and the constructor is called for s to use the set set in the function body.

Author: Vlad from Moscow, 2017-01-25

3 answers

If you want to use the default argument by reference, then this argument must not be a temporary object and must already be defined somewhere at the time of the function call.

Passing an argument by a non-const reference assumes that this original argument will be changed in the function. You can't pass temporary objects over a non-const link.

Therefore, based on the conditions specified in your question, most likely you should have two overloaded functions. One the function accepts an argument by lvalue - a reference with a specified object. The second function of the oibl accepts a temporary object by rvalue-sslka, the oibo uses the default value instead.

For example,

#include <iostream>

void func( int &i )
{
    ++i;
    std::cout << "Inside func( int & ) i = " << i << std::endl;
}   

void func( int &&i = int() )
{
    ++i;
    std::cout << "Insde func( int && ) i = " << i << std::endl;
}   


int main() 
{
    int i = 0;

    std::cout << "Before func( i ) i = " << i << std::endl;

    func( i );

    std::cout << "After  func( i ) i = " << i << std::endl;

    std::cout << std::endl;

    i = 0;

    std::cout << "Before func() i = " << i << std::endl;

    func();

    std::cout << "After  func() i = " << i << std::endl;

    return 0;
}

Program output to the console:

Before func( i ) i = 0
Inside func( int & ) i = 1
After  func( i ) i = 1

Before func() i = 0
Insde func( int && ) i = 1
After  func() i = 0

In this program, when lvalue is passed as an argument, the first function

void func( int &i )
{
    ++i;
    std::cout << "Inside func( int & ) i = " << i << std::endl;
}   

And it changes the original argument in its body.

When the argument is not specified, or when rvalue is specified, that is, some temporary object, such as

func(); // используется аргумент по умолчанию int(), который равен 0

Or

func( 10 ); // используется временный объект - целочисленный литерал - 10

Then the second function

void func( int &&i = int() )
{
    ++i;
    std::cout << "Insde func( int && ) i = " << i << std::endl;
}   

If you are not going to change the original argument, then it is enough to declare a single function with a parameter in the form of a constant reference. For example,

void func( const int &i = int() );
 4
Author: Vlad from Moscow, 2017-01-25 16:02:52

Well, the first case is simple - if you want to be able to use the default value, then use const int& -

void f(const int& i = 5)
{
    cout << i << endl;
}

Without const, as you understand, you will not be able to pass the value of - after all, what are you going to change by passing a number? :)

But this way-you can:

int j = 5;

void f(int& i = j)
{
    cout << i << endl;
}

int main(int argc, const char * argv[])
{
    int q = 4;
    f();
    f(q);
}

Accordingly, it is the same with set<int>& - as you imagine

For s, the constructor was called to use the set set in the body functions

I.e. you want to create a new set<int>? Then where should it be created? As a local variable, as a global variable, as a variable in the calling function?

So by default, you must specify an existing object for the link. The other just doesn't make any sense. After all, a link is just an address, waiting for which the correct object is guaranteed to exist.

"In my opinion, so " (c) Pooh

 4
Author: Harry, 2017-01-25 15:32:04

If you need a non-const link, then you can do something like

void func2(set<int> &s = some_function())

Where some_function is

set<int> &some_function()
{
  ...
}

A certain function that is responsible for creating these instances std::set in a certain storage. Separately, we will have to think about ensuring a certain policy of their subsequent destruction when they become unnecessary. How this will be done is a separate question, and there are no elegant solutions here offhand.

The optimal solution may depend on the specific the specifics of your task, but the idea of implicitly creating (potentially long-lived) objects via the default parameter is questionable.

 2
Author: AnT, 2017-01-25 15:40:29