This question already has answers here:
Ambiguous Reference/Value Versions of Functions
(4 answers)
Overload resolution between object, rvalue reference, const reference
(1 answer)
Ambiguous call with overloaded r-value reference function [duplicate]
(1 answer)
Closed 3 months ago.
Please refer to the below simple scenario:
void test(int k){
cout<<"Passed as value"<<endl;
cout<<k<<endl;
}
void test(int &k){
cout<<"Passed as reference"<<endl;
cout<<k<<endl;
}
int main(){
int x = 10;
test(x);
}
As far as my understanding is concerned, when you call a function, at that time the compiler has no way of knowing if the variable passed to it is by value or by reference. Thus, I understand why the compiler gives the error that call of overloaded ‘test(int&)’ is ambiguous. Is there any way that we can specify while calling the function itself that I intend to pass the value as reference?" N.B. I already know the work around this issue by passing the variable as address.
Related
This question already has answers here:
Why is the phrase: "undefined behavior means the compiler can do anything it wants" true?
(2 answers)
Returning const reference to temporary behaves differently than local const reference?
(3 answers)
Closed 5 months ago.
While playing around with references to lambdas I encountered a scenario where I expected the program to crash due to dangling references. In the following program, I assumed that the lambda argument to fn_x_3 in main is "moved to" the fn_x_3 function because it's an rvalue, where it binds to the lvalue fn.
#include <iostream>
#include <functional>
std::function<int(int)> fn_x_3(std::function<int(int, int)>& fn) {
// capture fn by reference!
return [&fn](int x) {
return fn(x, 3);
};
}
std::function<int(int)> fn_x_3(std::function<int(int, int)>&& fn) {
// passing fn (lvalue) by reference to fn_x_3 overload
return fn_x_3(fn);
}
int main()
{
// call to fn_x_3(function<int(int)>&& fn), lambda "moved into" the function
auto fn = fn_x_3([](int x, int y){ return x + y; });
int result = fn(2);
std::cout << result << std::endl;
return 0;
}
This program prints out 5. But when fn goes out of scope in fn_x_3(function<int(int,int)>&&), does this not invalidate the reference that is captured in fn_x_3(function<int(int,int)>&)?
It does, pretty much second function overload fn_x_3 is ok BUT if you use the return value in any way outside the scope of the function you are invoking UB by using object past its lifetime (the object is the underlying lambda structure of first fn_x_3 overload).
It is not enforced by the C++ compiler to block compilation of such programs.
If you want to find these kinds of error you could use so called address sanitizers.
Programs prints 5 - it is most likely due to the fact that the memory that you are accessing is still "bound" to the executable thus it doesn't see any access violations (std::function implementation detail)
This question already has answers here:
What are the differences between a pointer variable and a reference variable?
(44 answers)
Closed 2 years ago.
As an example I know that
void foo(int *num)
{
num++;
}
foo(&num);
will pass num by reference. However, why do people use
void foo(int &num)
{
num++;
}
I've heard that you should use that syntax over what I posted above, why is this?
Your first example passes by pointer, not reference.
The second example void foo(int &num) is a function that takes its argument by reference.
This question already has answers here:
assigning to rvalue: why does this compile?
(1 answer)
rvalue on the left side
(2 answers)
Closed 4 years ago.
In the code below, why doesn't the assignment to get_string_val() give compilation error ? It looks like the function is returning an rvalue.
Of course, this is a simple example and this could be a member function returning a member variable. This can cause a bad bug if I had intended to return std::string& but mis-typed and returned std::string.
It looks like "xxx" is getting assigned to a temporary variable returned by get_string_val() ?
std::string get_string_val()
{
std::string x;
return x;
}
int main()
{
get_string_val() = "xxx";
}
That is because std::string has an overloaded (custom) assignment operator. This operator can be invoked for rvalue std::string, as long as the object is not const-qualified.
You'd have a compilation error if your get_string would return const std::string.
By the way, things work differently for built-in types, which do not have operator= overloaded for them. int get_int(); get_int() = 25; would be a compilation error.
This question already has answers here:
how does the ampersand(&) sign work in c++? [duplicate]
(3 answers)
Closed 6 years ago.
I have this function:
void fun(int x, int& sum)
{
sum = x * x;
}
what is wrong with:
fun(4, &y);
fun(4,5);
&y is not a reference. It is a pointer to variable y. If you want to pass it by reference you just pass it like so:
fun(4, y);
In this function call
fun(4, &y);
argument y has type of pointer while the corresponding parameter is reference to int.
If y is defined like
int y;
then the valid function call will look like
fun(4, y);
This function call is invalid
fun(4,5);
because the second argument is a temporary expression that is not lvalue. Thus it may be bound to a constant reference. However the corresponding parameter is declared as a non-constant reference because the parameter is changed in the function. Thus the compiler will issue a diagnostic message.
This question already has answers here:
Function References
(5 answers)
Closed 8 years ago.
When to use function reference such as
void (&fr)() = foo;
fr();
instead of function pointer such as
void (*fp)() = &foo;
fp();
Is there something function pointer can't do but function reference can?
when you define a reference:
void (&fr)() = foo;
fr();
it gives you the ability to use fr almost everywhere where it would be possible to use foo, which is the reason why:
fr();
(*fr)();
works exactly the same way as using the foo directly:
foo();
(*foo)();
One more Difference is dereferencing a function reference doesn't result in an error where function pointer does not require dereferencing.