How to access the value of a const reference parameter? - c++

if I have a function set up similarly to this:
update_value(const int& old_value, const int& new_value){
}
What if I need to get the value of old_value and new_value and use these values in a mutable variable?
I can't dereference with a *pointer. How do I work around this?

First of all your question is not so clear and I dont know why you want to use mutable keyword.Mutable keyword can be used only for class member variables.
Regarding your question,in the comment you mentioned that you want to access some index of the array based on the passed arguments.Since you are not changing passed argument value you can directly use your passed argument in the accessing array value.

Related

Why my class keeps reseting and doesnt keep my changes [duplicate]

A simple question for which I couldn't find the answer here.
What I understand is that while passing an argument to a function during call, e.g.
void myFunction(type myVariable)
{
}
void main()
{
myFunction(myVariable);
}
For simple datatypes like int, float, etc. the function is called by value.
But if myVariable is an array, only the starting address is passed (even though our function is a call by value function).
If myVariable is an object, also only the address of the object is passed rather than creating a copy and passing it.
So back to the question. Does C++ pass a object by reference or value?
Arguments are passed by value, unless the function signature specifies otherwise:
in void foo(type arg), arg is passed by value regardless of whether type is a simple type, a pointer type or a class type,
in void foo(type& arg), arg is passed by reference.
In case of arrays, the value that is passed is a pointer to the first element of the array. If you know the size of the array at compile time, you can pass an array by reference as well: void foo(type (&arg)[10]).
C++ always gives you the choice: All types T (except arrays, see below) can be passed by value by making the parameter type T, and passed by reference by making the parameter type T &, reference-to-T.
When the parameter type is not explicitly annotated to be a reference (type &myVariable), it is always passed by value regardless of the specific type. For user-defined types too (that's what the copy constructor is for). Also for pointers, even though copying a pointer does not copy what's pointed at.
Arrays are a bit more complicated. Arrays cannot be passed by value, parameter types like int arr[] are really just different syntax for int *arr. It's not the act of passing to a function which produces a pointer from an array, virtually every possible operation (excluding only a few ones like sizeof) does that. One can pass a reference-to-an-array, but this explicitly annotated as reference: int (&myArray)[100] (note the ampersand).
C++ makes both pass by value and pass by reference paradigms possible.
You can find two example usages below.
http://www.learncpp.com/cpp-tutorial/72-passing-arguments-by-value/
http://www.learncpp.com/cpp-tutorial/73-passing-arguments-by-reference/
Arrays are special constructs, when you pass an array as parameter, a pointer to the address of the first element is passed as value with the type of element in the array.
When you pass a pointer as parameter, you actually implement the pass by reference paradigm yourself, as in C. Because when you modify the data in the specified address, you exactly modify the object in the caller function.
In C++, types declared as a class, struct, or union are considered "of class type". These are passed by value or you can say a copy using copy constructor is passed to the functions. This is pretty evident when we implement binary trees wherein you almost always have a Node * type of param in the recursive function acting on the binary tree. This is so as to facilitate modification of that node. If the node were to be passed as is (i.e not being a pointer type), the modifications to the nodes would have been to the local copy. Even in the case of vectors, while passing a copy of vectors is passed to the functions, to avoid which we use a reference &.
C++ passes arguments that are no pointers (int*) or references (int&) by value. You cannot modify the var of the calling block in the called function. Arrays are pointers.

Using Bit-wise operators with an Enum and an unsigned char - Results in 0 [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What's the difference between passing by reference vs. passing by value?
I read that in C arguments are passed by value, but what's is the difference between passing arguments by value (like in C) or by refencence (like C++ - C#)?
What's the difference between a pointer and a reference?
void with_ptr(int *i)
{ *i = 0; }
void with_ref(int &i)
{ i = 0; }
In these cases are modified both value? If yes, why C++ allows to pass arguments by reference? I think it is not clear inside the function that the i value could be modified.
what's is the difference between passing arguments by value or by reference
If you pass by value, changes to the variable will be local to the function, since the value is copied when calling the function. Modifications to reference arguments will propagate to the original value.
What's the difference between a pointer and a reference?
The difference is largely syntactic, as you have seen in your code. Furthermore, a pointer can be reassigned to point to something else (unless it’s declared const), while a reference can’t; instead, assigning to a reference is going to assign to the referenced value.
I think it is not clear inside the function that the i value could be modified.
On the contrary, it’s absolutely clear: the function signature tells you so.
There’s actually a case to be made that it’s not clear outside the function. That’s why original versions of C# for instance mandated that you explicitly annotate any by-reference calling with ref (i.e. f(ref x) instead of plain f(x)). This would be similar to calling a function in C++ using f(&x) to make it clear that a pointer is passed.
But in recent versions of C#, the use of ref for calling was made optional since it didn’t confer enough of an advantage after all.
Consider this:
1) Passing by reference provides more simple element access i instead of *i
2) Generally you cannot pass null reference to a method, but can pass a null pointer
3) You can't change the address of reference, but can change it for a pointer(although, as pointer itself passed by value, this change will be discarded upon function exit)
Hope, this helped a bit
Actually, in the first case, you can't modify the argument. The pointer itself is immutable, you can only modify the value it points to.
If yes, why C++ allows to pass arguments by reference?
Because pointers can very easily be miss-used. References should almost always be prefered. For your case, what if you pass a NULL to with_ptr? You'll get undefined behavior, which is not possible if you use with_ref.
I think it is not clear inside the function that the i value could be modified.
It is very clear. If you see a function that takes a parameter by non-const reference, you can assume it will be changed.
I think that a method can only change an argument's value, if this is passed by reference. If you pass a argument by value in a method, then whatever change you make to its value, this will no be available in the parent method.
As far as I know, I think the reference is safer to use in a sense that it can't be modified (always points to the same thing), and should be initialized if it's a local variable. Pointer, however, can be change to point to somewhere else.
int x = 10;
int &y = x;
int *p = &x;
p++; //Legal if you know what's next
y++; // Increases the value of x. Now x = y = 11;
As my two cents, I think reference variables are mere alternative names for the same memory address by which it was initialized. This also explains pretty nice:
http://www.dgp.toronto.edu/~patrick/csc418/wi2004/notes/PointersVsRef.pdf

is correct to change argument value inside function

In this code I change iType variable which is a function parameter. It works fine, but is it correct?
void ImgCoreQCV::IPThreshold( double dThresh, double dMaxval, int iType, bool bTreshOtsu ) {
if(bTreshOtsu)
iType |= THRESH_OTSU;
if(undoVector.back().channels()!=1)
cvtColor(undoVector.back(),CurImg,CV_BGR2GRAY);
threshold(CurImg,CurImg,dThresh,dMaxval,iType);
}
I mean that I did not create a new variable and has changed it:
int iThreshType = iType;
if(bTreshOtsu)
iThreshType = iType | THRESH_OTSU;
threshold(CurImg,CurImg,dThresh,dMaxval,iThreshType);
It is correct in this particular case, and it has no side effect since the argument here is a copy of the actual parameter passed.
But it might make a trouble in general case, if you unintentially change parameter passed by reference.
Also modifying parameters usually make the code worse readable. And might require more time for understanding what is really happening in the function.
So, generally I wouldn't recommend modifying parameters. Leave this optimization to the compiler.
As long you don't have by reference parameters, changing the value won't have any effect outside of your function.
It's fine to do so and you don't need a extra variable.
You can create a temporary variable inline of the lowest function call like this:
threshold(CurImg,CurImg,dThresh,dMaxval, bTreshOtsu ? iType|THRESH_OTSU : iType);
There are a couple of things that you should be clear on regarding function parameters:
void IPThreshold( double dThresh, double dMaxval, int iType, bool bTreshOtsu );
The above function will pass copies of each of the parameter values to the function body. When invoked with a local variable then the value of the local variable is unchanged after you modify it in the function.
void IPThreshold( double& dThresh, double& dMaxval, int& iType, bool bTreshOtsu );
Above the function will use non-const references which means that you can modify the value of the referenced parameter within the function. If you call this version with a local variable and you modify the parameter then the local variable will be modified after the call returns.
You also ask if this is okay... well I personally attempt not to use parameters for this if I can avoid it as I think that return values are generally clearer. However there is nothing wrong with it. The only caveat I would say is that you should be consistent with the meaning of how you pass your parameters.

What's the difference between passing argument by value and by reference? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What's the difference between passing by reference vs. passing by value?
I read that in C arguments are passed by value, but what's is the difference between passing arguments by value (like in C) or by refencence (like C++ - C#)?
What's the difference between a pointer and a reference?
void with_ptr(int *i)
{ *i = 0; }
void with_ref(int &i)
{ i = 0; }
In these cases are modified both value? If yes, why C++ allows to pass arguments by reference? I think it is not clear inside the function that the i value could be modified.
what's is the difference between passing arguments by value or by reference
If you pass by value, changes to the variable will be local to the function, since the value is copied when calling the function. Modifications to reference arguments will propagate to the original value.
What's the difference between a pointer and a reference?
The difference is largely syntactic, as you have seen in your code. Furthermore, a pointer can be reassigned to point to something else (unless it’s declared const), while a reference can’t; instead, assigning to a reference is going to assign to the referenced value.
I think it is not clear inside the function that the i value could be modified.
On the contrary, it’s absolutely clear: the function signature tells you so.
There’s actually a case to be made that it’s not clear outside the function. That’s why original versions of C# for instance mandated that you explicitly annotate any by-reference calling with ref (i.e. f(ref x) instead of plain f(x)). This would be similar to calling a function in C++ using f(&x) to make it clear that a pointer is passed.
But in recent versions of C#, the use of ref for calling was made optional since it didn’t confer enough of an advantage after all.
Consider this:
1) Passing by reference provides more simple element access i instead of *i
2) Generally you cannot pass null reference to a method, but can pass a null pointer
3) You can't change the address of reference, but can change it for a pointer(although, as pointer itself passed by value, this change will be discarded upon function exit)
Hope, this helped a bit
Actually, in the first case, you can't modify the argument. The pointer itself is immutable, you can only modify the value it points to.
If yes, why C++ allows to pass arguments by reference?
Because pointers can very easily be miss-used. References should almost always be prefered. For your case, what if you pass a NULL to with_ptr? You'll get undefined behavior, which is not possible if you use with_ref.
I think it is not clear inside the function that the i value could be modified.
It is very clear. If you see a function that takes a parameter by non-const reference, you can assume it will be changed.
I think that a method can only change an argument's value, if this is passed by reference. If you pass a argument by value in a method, then whatever change you make to its value, this will no be available in the parent method.
As far as I know, I think the reference is safer to use in a sense that it can't be modified (always points to the same thing), and should be initialized if it's a local variable. Pointer, however, can be change to point to somewhere else.
int x = 10;
int &y = x;
int *p = &x;
p++; //Legal if you know what's next
y++; // Increases the value of x. Now x = y = 11;
As my two cents, I think reference variables are mere alternative names for the same memory address by which it was initialized. This also explains pretty nice:
http://www.dgp.toronto.edu/~patrick/csc418/wi2004/notes/PointersVsRef.pdf

How do I write a const accessor that returns a reference to a member object, so it might be edited?

Here is the problem. I wrote this function to return a reference to the i element of a member vector, so this element could be edited. Here is the code:
Letter& Literal::get (int i) const {
return lit_m.at (i); //Vector of Letter objects
}
But g++ won't let me assign that element to a non-const reference:
g++ -o literal.o -c literal.cpp
literal.cpp: In member function ‘Letter& Literal::get(int) const’:
literal.cpp:34: error: invalid initialization of reference of type ‘Letter&’ from expression of type ‘const Letter’
How could it be solved? My idea is to build up a function like the at() function of vectors, so it would be const as it doesn't edit the object itself, but it should let me edit the returned object...Is it possible?
SOLVED: I just had to overload the function :), so declare a const and a non-const version. I was afraid that const and non-const overloading wasn't permitted, but I saw that that const changes the argument list, making it possible.
The problem is this member function :
Letter& get (int i) const
you declared it const, and because of that,
const T& at() const
member function of the vector class is called, returning you const reference to the i-th item, therefore you can not modify it.
If you really need to modify that element, do not declare your get() function as const, and return reference to the element like you are doing now.
by the way, you declared the function const, and you are returning non-const reference.
There's a very good reason why this produces an error. The object of your class should be constant to preserve its state. When you return a reference to one of its internal variables, you're allowing someone to change the value of that internal variable, thus changing the state of the object, making it no longer a constant function.
Something that might be possible is if the Literal class contained a vector of pointers to Letter objects instead of letter objects, you can successfully return a ponter to one of those Letter objects without issues.
Letter* Literal::get (int i) const {
return lit_m.at (i); //Vector of pointers to Letter objects
}
Probably an article everyone dealing with pointers should read (or any language allowing the const keyword, but 10x more so if pointers are involved) can be found here. Honestly, I probably should look over it again myself.
That isn't const-correct. You are changing a member variable of the class (the vector), so g++ is seeing this as an error. When you declare a method as const and return a member variable the expectation is that the value returned is used for inspection not mutation.