JACK M
JACK M

Reputation: 2841

C++: pass reference as parameter but that function doesn't accept reference as parameter

I have this code snippet from here. Pls have a look at the file spec.cc.

Eval parse_recursive_descent (Grammar g, SymbolString input) {
    return
        parse_recursive_descent
            (g, Stack (SymbolString {g.start}, input, Path ())) ;
}

// MAIN ////////////////////////////////////////////////////////////////////////

int main () {
    Input in = read_input (std::cin) ;
    Eval  ev = parse_recursive_descent (grammar (in), string (in)) ;
    print (make_output_string (derivations (ev), accept (ev))) ;
    return 0 ;
}

The prototype of function grammar is: Grammar& grammar (Input& in) ;. So it returns a reference.

But parse_recursive_descent doesn't have the g parameter as reference. The question is: the g in function parse_recursive_descent is a reference or a value?

Upvotes: 0

Views: 76

Answers (3)

infinite loop
infinite loop

Reputation: 1319

Its a basic thing that you can assign a reference to a variable of the same type like:

int i = 10;
int& j = i;
int k = j;//here j is a reference and value from j is copied to k

Here, as you said function grammar returns a reference of type Grammar. Now this returned value is sent to function parse_recursive_descent as an argument (to Grammar g). So it is as simple as assigning a variable of type Grammar to g.

Grammar g = variable of type Grammar; //this is a value copy

So, g is simply a value not a reference.

*Copy happens in copy constructor of Grammar class.

Upvotes: 1

Matteo Italia
Matteo Italia

Reputation: 126777

It's a value, copy-constructed from the reference you pass as argument.

The general idea is that all the parameters of a function are variables (of the specified type) local to the function. When you pass an argument, it is used as the initializer to construct the corresponding parameter.

Upvotes: 3

Pete Becker
Pete Becker

Reputation: 76245

Eval parse_recursive_descent(Grammar g, SymbolString input)

g is a value of type Grammar. You know that because that's what the declaration says.

When you call the function, if the type that's passed doesn't exactly match the type that the function is expecting, the compiler generates code to make them match. So in the call

parse_recursive_descent(grammar(in), string(in));

the compiler converts the reference returned by grammar(in) into an object of type Grammar and passes that to parse_recursive_descent. To make the object it sets aside space for an object of type Grammar and uses the copy constructor, passing the reference that grammar(in) returns. You could do something similar like this:

Grammar temp(grammar(in));
parse_recursive_descent(temp, string(in));

The only difference if you do it that way is that you would have a named object (temp) instead of the (unnamed) temporary object that the compiler creates in your actual code.

Upvotes: 0

Related Questions