Converting a float to float* - c++

I have QStandardItem* list in my code
QList<QStandardItem*> lst
Now this is acceptable and works
float a = lst[0]->text().toFloat();
However the following does not work
float* a = &(lst[0]->text().toFloat());
I get an intellisense error stating
Expression must be an lvalue or a function designator
I need a pointer here since I am using an external library that requires a reference that looks like this
some_class.add_variable(const std::string& variable_name, float& t);
So if I get a pointer I could simply pass it as *a
Any suggetsions on how I could resolve this issue ?

The right hand side is what's called a temporary. It is an object which will not exist after the end of the current expression. For obvious reasons, you can't take the address of temporaries; after the expression ends you'd have an invalid pointer.
What you could do is this:
float a = lst[0]->text().toFloat();
float* aPtr = &a;
That will safely make a copy of the temporary value (or in C++11, it may move the temporary), and you can then take a reference to your local, non-temporary variable.

Use float a = lst[0]->text().toFloat(); and simply pass it as &a to the library function.

Taking the address of a temporary value returned by a function is not going to work. This value is supposed to be assigned to an lvalue variable.
Why do you want the address of the float instead of the actual value?
You should only be dealing with addresses of, or pointers to values that have been saved somewhere.

Actually, your external function does NOT need an address, it takes a REFERENCE, so you don't need a pointer.
However, if you really need the pointer to a local variable:
float x = something...;
some_function(&x);
will give you what you are after.

Take care: float* a = &(lst[0]->text().toFloat()); will give you undefined behaviour if you refer to a following this statement. This is because the anonymous temporary (the float returned by .tofloat()) will be out of scope after the statement and a will be invalidated; i.e. will not point to anything meaningful.
You should write float a = lst[0]->text().toFloat(), and pass &a to the function. That is, keep a in scope for as long as you need it.

Related

Trying to convert char* to wchar_t* in function. losing string on returning [duplicate]

Is passing pointer argument, pass by value in C++? Since i see that any change to the pointer as such is not reflected outside the method. The changes i do by dereferencing the pointer is reflected though.
In that case, is it acceptable/standard procedure to use pointer to pointer as argument to a function to modify the pointer value as such within a function?
Yes to both.
Pointers are passed by value as anything else. That means the contents of the pointer variable (the address of the object pointed to) is copied. That means that if you change the value of the pointer in the function body, that change will not be reflected in the external pointer that will still point to the old object. But you can change the value of the object pointed to.
If you want to reflect changes made to the pointer to the external pointer (make it point to something else), you need two levels of indirection (pointer to pointer). When calling functions it's done by putting a & before the name of the pointer. It is the standard C way of doing things.
When using C++, using references is preferred to pointer (henceforth also to pointer to pointer).
For the why references should be preferred to pointers, there is several reasons:
references introduce less syntaxic noise than pointers in function body
references keep more informations than pointers, than can be useful for compiler
Drawbacks of references are mostly:
they break the simple pass-by-value rule of C, what makes understanding the behavior of a function regarding of parameters (will they be changed ?) less obvious. You also need function prototype to be sure. But that is not really worse than the multiple pointer levels necessary when using C.
they are not supported by C, that can be a problem when you write code that should work with both C and C++ programs (but that's not the most usual case).
In the specific case of pointer to pointer, the difference is mostly simplicity, but using reference it may also be easy to remove both levels of pointers and pass only one reference instead of a pointer to pointer.
I understand the confusion here. The concepts of "pass by value" and "pass by reference" are not so clear even if they seem to be so.
Bear in mind that the computer does not know these concepts and does not behave according to it.
The computer does not know about the types. Hence it does not make a distinction of pointers and values.
Let me try to explain by and example:
void func1(int x) //copy some value to local variable x (of type int)
{
x = 5; //modify local variable. lost after function call
}
void func2(int *x) //copy some value to local variable x (of type int*)
{
int a;
x = &a; //modify local variable. lost after function call.
}
void func3(int *x) //copy some value to local variable x(of type int*)
{
*x = 10; //x is local but *x is not! change is saved after function call!
}
func1 and func2 are identical. Both modify a local variable. Modification is lost after function is popped off the stack.
func3 has ability to change another memory location (a variable which is not local to the function).
basically, every function call is "call by value". But in the case of a pointer type, we have a way to change the content of a remote address in memory.
Pass by value using Pointers
I'll explain it by example:
void f(int *ptr)
{
cout<<*ptr;
}
int main ()
{
int a=10;
int *aptr=&a;
f(aptr);
return 0;
}
Here, in main function a is an integer variable whose content is 10 and address is 00F8FB04 (assume).
aptr is pointer to integer, that store the address of integer variable a, so aptr content is address of integer variable a that is 00F8FB04. When we pass aptr as the function argument only content of aptr (that is address) are copies to function parameter.
So, ptr will receive the copy of content of aptr (that is address 00F8FB04)
Either a pointer to a pointer, or a reference to a pointer, is what you would use if you wanted to potentially change the pointer itself. To your original question, technically, yes, all parameters are passed by value.
Yes it is, as it is in C.
In that case, is it acceptable/standard procedure to use pointer to pointer as argument to a function to modify the pointer value as such within a function?
In which case? What do you want? You can use real references with the & modifier.
void func(type &ref);

How to pass the unique pointer to specific param required in function?

A short yet effective example below:
std::unique_ptr<float> x(new float[whatever_size]);
I have a function with prototype:
void function(float*&);
How can I go about calling it by passing in the x.
I tried:
function(x.get()); // complains no argument matches float*&
function(&x.get()); // complains requires lvalue.
A short answer with an explanation would be great.
Thanks!
To start with, you should know that a unique pointer doesn't magically protect you from messing up memory management. Your use case is extremely fishy, and I would caution you to not assume a unique pointer will solve everything and anything.
function expects a modifiable lvalue reference. The call x.get() returns an rvalue. Naturally the reference won't bind to it, no matter how hard you try. Now, the obvious solution is to introduce a temporary:
auto *f = x.get();
function(f);
But that may come back and shoot you in the foot if function needs to actually modify f, the pointer and not the pointee.
Since you mentioned it a comment that it indeed modifies its argument. You must reliniquish ownership from the unique pointer before the call, and give it back after:
auto *f = x.release();
function(f);
x.reset(f);
That is the only way the change will reflect in x. But again, it's still a bit fragile.
The problem here is that the function can modify the pointer you pass to it (passed by non-const reference), potentially re-seating it. If that is the case, then you would have to do something like this:
std::unique_ptr<float[]> x(new float[N]); // remember the array type []
float* fp = x.release();
func(fp);
x.reset(fp);
But the critical point is passing in a proper (named) pointer, not just a temporary pointer returned by x.get().
Your error occurs because the function is unable to modify the temporary pointer returned by the function x.get(). You have to give it a real pointer that can change value.

What actually happens when passing by reference

When I pass a variable by reference like this:
void function(int &r){
//do something
}
int main(){
int a = 100;
function(a);
return 0;
}
What actually happens ? Does r contain the address of an integer variable or something ? How does it find it ?
Reference of your integer a will be passed as argument to your function. Now in your function, if you change the value pointed by r, it will be reflected in a as well.
So if you assign r=2 in your function and print out a in main, you will see that a has the value 2.
Your program has some syntax errors, but I can understand what you wanted to convey.
Edit:
From the user perspective, it's as if you were receiving a value in the function except that modification done to it are visible from the caller. It's also cheaper in terms of performance when passing big objects because no copy is needed.
How it works in practice is that the compiler actually pass a pointer to the function. But since the caller must have a valid object to pass to the function, a reference can't be invalid contrary to a pointer so you don't need to check for NULL values.

can we assign a integer value to a reference variable?

It is not possible to assign an integer value to a reference variable directly, say like:
int &x=10; //not possible
Is there any other way we can modify this statement to make it possible?
But not like this:
int a=10;int &x=a;
This works fine. But I want some other way or modify a little bit my expression and make it work!
The reference as the name says has to reference to something. How do you want to assign a value to it if it doesn't reference anything?
The reason it doesn't work is because 10 is of the type "const int". You can turn that into a reference, but you can't make it non-const without violating some logic at the least.
const int &a = 10;
that'll work.
int &b = const_cast<int &>(static_cast<const int &>(10));
will also compile, but you can't modify b (as that would imply modifying the actual "10" value).
The crux is that 10 is a constant – somewhat obviously: you cannot change its value. But if you try to assign it to an int reference, this would mean that the value were modifiable: an int& is a modifiable value.
To make your statement work, you can use a const reference:
int const& x = 10;
But as “cnicutar” has mentioned in a comment, this is pretty useless; just assign the 10 to a plain int.
You can't bind a reference-to-nonconst to anything immutable.
The standard permits storing compile time constants in ROM (btw, attempting to modify const_cast<>ed compile time constants yields undefined behaviour)
This would basically strip of the const, even if the const is invisible, therefore subverting the whole const-correctness-thing
However, you can bind a reference-to-const to nearly everything, including temporaries:
GotW: A candidate for the most important const
Consider this a "feature".
References refer to objects (perhaps temporary objects), not to values. If you want to store a value somewhere, assign it to an object, not to a reference.
As a special case, const int &a = 10; initializes the reference a to refer to a temporary object with the value 10, and it extends the lifetime of that temporary to the end of the scope of a (12.2/5). That's pretty useless with an integer literal, but occasionally useful with objects of class type. Still, this does not assign an integer value to a reference. It creates a temporary, and binds a reference to the temporary.
in the C++0x, you can use int&& (rvalue references ), but this can be used as function parameter.

Use of the & operator in C++ function signatures

I'm currently reading through Accelerated C++ and I realized I don't really understand how & works in function signatures.
int* ptr=&num;
means that ptr now holds the address to num, but what does that mean?
void DoSomething(string& str)
from what I understand that is a pass by reference of a variable (which means passing the address) but when I do
void DoSomething(string& str)
{
string copy=str;
}
what it creates is a copy of str. What I thought it would do is raise an error since I'm trying to assign a pointer to a variable.
What is happening here? And what is the meaning of using * and & in function calls?
A reference is not a pointer, they're different although they serve similar purpose.
You can think of a reference as an alias to another variable, i.e. the second variable having the same address. It doesn't contain address itself, it just references the same portion of memory as the variable it's initialized from.
So
string s = "Hello, wordl";
string* p = &s; // Here you get an address of s
string& r = s; // Here, r is a reference to s
s = "Hello, world"; // corrected
assert( s == *p ); // this should be familiar to you, dereferencing a pointer
assert( s == r ); // this will always be true, they are twins, or the same thing rather
string copy1 = *p; // this is to make a copy using a pointer
string copy = r; // this is what you saw, hope now you understand it better.
The & character in C++ is dual purpose. It can mean (at least)
Take the address of a value
Declare a reference to a type
The use you're referring to in the function signature is an instance of #2. The parameter string& str is a reference to a string instance. This is not just limited to function signatures, it can occur in method bodies as well.
void Example() {
string s1 = "example";
string& s2 = s1; // s2 is now a reference to s1
}
I would recommend checking out the C++ FAQ entry on references as it's a good introduction to them.
https://isocpp.org/wiki/faq/references
You shouldn't know anything about pointers until you get to chapter 10 of Accelerated C++ !
A reference creates another name, an alias, for something that exists elsewhere. That's it. There are no hidden pointers or addresses involved. Don't look behind the curtain!
Think of a guy named Robert
guy Robert;
Sometimes you may want to call him Bob
guy& Bob = Robert;
Now Bob and Robert both refer to the same guy. You don't get his address (or phone number), just another name for the same thing.
In your function
void DoSomething(string& str)
{
  string copy=str;
}
it works exactly the same, str is another name for some string that exists somewhere else.
Don't bother with how that happens, just think of a reference as a name for some object.
The compiler has to figure out how to connect the names, you don't have to.
In the case of assigning variables (ie, int* ptr = &value), using the ampersand will return the address of your variable (in this case, address of value).
In function parameters, using the ampersand means you're passing access, or reference, to the same physical area in memory of the variable (if you don't use it, a copy is sent instead). If you use an asterisk as part of the parameter, you're specifying that you're passing a variable pointer, which will achieve almost the same thing. The difference here is that with an ampersand you'll have direct access to the variable via the name, but if you pass a pointer, you'll have to deference that pointer to get and manipulate the actual value:
void increase1(int &value) {
value++;
}
void increase2(int *value) {
(*value)++;
}
void increase3(int value) {
value++;
}
Note that increase3 does nothing to the original value you pass it because only a copy is sent:
int main() {
int number = 5;
increase1(number);
increase2(&number);
increase3(number);
return 0;
}
The value of number at the end of the 3 function calls is 7, not 8.
It's a reference which allows the function to modify the passed string, unlike a normal string parameter where modification would not affect the string passed to the function.
You will often see a parameter of type const string& which is done for performance purposes as a reference internally doesn't create a copy of the string.
int* ptr=&num;
1st case: Since ptr is a memory and it stores the address of a variable. The & operator returns the address of num in memory.
void DoSomething(string& str)
2nd case: The ampersand operator is used to show that the variable is being passed by reference and can be changed by the function.
So Basically the & operator has 2 functions depending on the context.
While pass by reference may be implemented by the compiler by passing the address as a pointer, semantically it has nothing to do with addresses or pointers. in simple terms it is merely an alias for a variable.
C++ has a lot of cases where syntax is reused in different contexts with different semantics and this is one of those cases.
In the case of:
int* ptr=&num;
you are declaring a variable named ptr with a type of an int * (int pointer), and setting its value to the "address of the variable num" (&num). The "addressof" operator (&) returns a pointer.
In the case of:
void DoSomething(string& str)
you are declaring the first parameter of the DoSomething() method to be of type "reference to string". Effectively, this is the C++ way of defining "pass-by-reference".
Note that while the & operator operates similarly in these cases, it's not acting in the same way. Specifically, when used as an operator, you're telling the compiler to take the address of the variable specified; when used in a method signature, you're telling the compiler that the argument is a reference. And note as well, that the "argument as a reference" bit is different from having an argument that is a pointer; the reference argument (&) gets dereferenced automatically, and there's never any exposure to the method as to where the underlying data is stored; with a pointer argument, you're still passing by reference, but you're exposing to the method where the variable is stored, and potentially exposing problems if the method fails to do a dereference (which happens more often than you might think).
You're inexplicitly copy-constructing copy from str. Yes, str is a reference, but that doesn't mean you can't construct another object from it. In c++, the & operator means one of 3 things -
When you're defining a normal reference variable, you create an alias for an object.
When you use it in a function paramater, it is passed by reference - you are also making an alias of an object, as apposed to a copy. You don't notice any difference in this case, because it basically is the object you passed to it. It does make a difference when the objects you pass contain pointers etc.
The last (and mostly irrelevent to your case) meaning of & is the bitwise AND.
Another way to think about a reference (albeit slightly incorrect) is syntactic sugar for a dereferenced pointer.