fightermagethief
fightermagethief

Reputation: 322

Is a copy made when passing by 'implied'(?) reference in C++

If I have a function that takes a reference to a map:

pair<int,int> myFunc(map<int,char> &myVar){...}

I can pass it a map without needing the '&'.

myFunc(someMapitoa);

Is there any difference? Is a copy made and then thrown away? Should I use the '&' anyway?

Upvotes: 1

Views: 1111

Answers (2)

erapert
erapert

Reputation: 1413

C++ is pass-by-value by default.

So, this makes a copy:

void foo (bar b);

This does not:

void foo (bar & b);

This makes a copy of a pointer, but not the actual data that it points to:

void foo (bar * b);

If you really want to get deeper into it then see this SO post about move semantics.

Anyway, for the above three examples they are all called the same way:

#include <iostream>
using namespace std;

int alpha (int arg) {
    // we can do anything with arg and it won't impact my caller
    // because arg is just a copy of what my caller passed me
    arg = arg + 1;
    return arg;
}

int bravo (int & arg) {
    // if I do anything to arg it'll change the value that my caller passed in
    arg = arg + 1;
    return arg;
}

int charlie (int * arg) {
    // when we deal with it like this it's pretty much the same thing
    // as a reference even though it's not exactly the same thing
    *arg = *arg + 1;
    return *arg;
}

int main () {
    int a = 0;

    // 1
    cout << alpha (a) << endl;
    // 1
    cout << bravo (a) << endl;
    // 2
    cout << charlie (&a) << endl;

    return 0;
}

Upvotes: 5

Brian Bi
Brian Bi

Reputation: 119477

You should think of this in terms of what is being initialized from what.

When you call a function, each argument is used to initialize the corresponding parameter. If the parameter is declared with reference type, it's a reference. If the parameter is not declared with reference type, it's an object.

  • The initialization of a reference to class type T from an expression of type T never makes a copy.
  • The initialization of an object of class type T from an expression of type T either copies or moves.

The rules here are the same as the rules for initializing non-parameter variables, as in:

T t = ...
T& r = ...

The fact that a function may take a reference to an argument even when there is no explicit notation at the call site is viewed by some as confusing. This is why some style guides ban non-const reference parameters (such as the Google C++ style guide) and force you to declare the argument as a pointer so that & must be used at the call site. I don't advocate this coding style, but it is an option you might want to consider.

Upvotes: 2

Related Questions