int foo(int x);
x is a copy of the passed value (a copy is made)
int foo(int& x);
x is a reference to the passed value
int foo(int* x);
x is a pointer to some value
The problem is not that you are passing i by reference (I believe that is happened because you are calling it inside a function where i is a reference), but the fact that you are passing pointers where the function expects normal values (to convert to references).
I am indeed confused. What I want to do, is pass the first three arguments by value, and the final two by reference.
Is my function declaration not doing just that?
I'm also getting a "note:"
candidates are: int DemodShaperFilterCell::cycle(int, int, int, int&, int&)
which suggests to me that the declaration is correct. So, I assumed that my problem was how I formed the call, and in the first and third arguments (which are the only two that disagree with the candidate.
As for your assumption, it was incorrect. An int* is not the same thing as an int&. If you want an int&, you either pass an int and let the function get the reference itself (normal) or you pass a reference yourself (generally inside of a function where you might already have a reference).
I'm away from my work computer right now, so I can't test. Do I correctly understand you that the function declaration should be (int, int, int, int, int)?
foo(i) could either be passing i as a copy or as a reference, depending on how foo is defined.
I'm not completely sure what you mean. Do you mean you have some function foo(), that has an int i in it, and it calls bar(i), but does not want bar to modify i?
What I meant was, in the old C days, a programmer could write a call to a function:
y = fn(x); // fn defined elsewhere
and know that x was not going to be changed, because it's being passed by value.
But, this doesn't seem true anymore in C++, where fn() could treat x as a reference and alter it.
Just an observation, but it seems like passing arguments is a bit "riskier" in C++ than it was in C. The assumption that this wasn't the case was really the basis for my confusion that spawned this thread.
Just an observation, but it seems like passing arguments is a bit "riskier" in C++ than it was in C.
It is but it isn't. The API (declaration) of the function should tell you whether or not it intends to modify the argument. (Non-const reference indicates intent to modify). But in most cases you should be able to infer it without even looking at the argument, because in most cases you can decide whether or not it would "make sense" for the function to modify or not modify the argument.
OK, so then the "proper" way for my function prototype to be coded would be: cycle (constint, constint, constint, &int, &int);
Is that correct? (And of course the function definition would have to match.)
I think I'm beginning to see why C++ people make a bigger deal out of using the const tag than do C people.
Taking a parameter by const int is the same as by int since in both cases it is by value, and the function cannot
modify the caller's parameter in either case.
const is important for two reasons. First, it is part of the API specification for a function. Second, there is a small blurb in the standard that says that non-const references cannot bind to temporaries. In other words, if you had:
1 2 3 4
void print_me( std::string& s )
{
std::cout << s << std::endl;
}
then:
1 2 3 4 5 6 7
int main() {
std::string hello_world = "Hello World!";
print_me( hello_world ); // will compile
print_me( "Good bye world" ); // will not compile - compiler creates a temporary std::string to pass to function
print_me( std::string( "Good bye world" ) ); // will not compile - explicit temporary is being passed to function
}
However, if the function were declared as taking a const reference, then all of the above lines would compile fine.