in C++, why my pointer to a function cannot be initialized? - c++

in C++, why my pointer to a function cannot be initialized ?
double (*ptrF)(double&) = NULL;
double func(double& x)
{
return x*x;
}
ptrF= &func;
double aFunc(double target, double start, double tolerance, double (*ptrF)(double&) )
void findSqrt()
{
double myF = 2.0 ; double myStart = 1.1 ;
double t = aFunc(myF, myStart , ptrF);
cout << "myF sqrt root is " << t << endl ;
}
I got error:
error: expected constructor, destructor, or type conversion before '=' token
error: cannot convert 'double (*)(double&)' to 'double' for argument '3' to 'double newton(double, double, double, double (*)(double&))'
thanks

Code can not be run outside a function.
This is trying to run code:
ptrF= &func;
This is because it is not a declaration.
If you move this to inside a function it ill work
Alternatively you can initialize it at the declaration point.
double (*ptrF)(double&) = &func;
Insufficient parameters:
aFunc(myF, myStart , ptrF);
// ^^^^ Missing a double here
Notice you are only passing three arguments. This function takes four. So you are passing a function pointer as a parameter that is only expecting a double.

You have two separate bugs:
error: expected constructor, destructor, or type conversion before '=' token
You cannot write an assignment
ptrF= &func;
outside of any function. Move the declaration of ptrF below the definition of func and make it an initialization instead, which you can write at file scope, as alk suggested. The & in &func is also unnecessary.
error: cannot convert 'double (*)(double&)' to 'double' for argument '3' to 'double aFunc(double, double, double, double (*)(double&))'
You are passing only three arguments to aFunc, but it wants four. Add a tolerance argument and the "cannot convert" error should go away. (I don't know why GCC doesn't give you another error message telling you that you gave the wrong number of arguments. It does for C.)

You might try this:
double func(double& x)
{
return x*x;
}
double (*ptrF)(double&) = func;
...
double t = aFunc(myF, myStart , 0., ptrF);

double aFunc(double target, double start, double tolerance, double (*ptrF)(double&) )
Were you trying to do with the above line - function declaration (or) function definition?! either way its wrong/in-complete.
And you're calling aFunc as follows:
double t = aFunc(myF, myStart , ptrF);
One obvious thing I could see it, there is a signature mismatch between the way aFunc is declared/defined (as per the first line in this post - 4 arguments) and called (3 arguments)
There are multiple errors/issues, but to proceed further, you need to correct the above mentioned issue first!

Related

function overloading in C++ not working when parameters differ by type [duplicate]

I'm trying
void function(int y,int w)
{
printf("int function");
}
void function(float y,float w)
{
printf("float function");
}
int main()
{
function(1.2,2.2);
return 0;
}
I get an error error like..
error C2668: 'function' : ambiguous call to overloaded function
and when I try to call function(1.2,2) or function(1,2.2) it is printing as "int function"
Please clarify when will the function(float y,float w) be called?
Look at the error message from gcc:
a.cpp:16: error: call of overloaded ‘function(double, double)’ is ambiguous
a.cpp:3: note: candidates are: void function(int, int)
a.cpp:9: note: void function(float, float)
A call to either function would require truncation, which is why neither is preferred over the other. I suspect you really want void function(double y,double w). Remember that in C/C++, the default floating-point type for literals and parameter passing is double, NOT float.
UPDATE
If you really don't want to change the function signature from float to double, you can always use literals that are typed as float. If you add the suffix f to the floating point numbers, they will be typed float.
Your examples would then be function(1.2f, 2f) and function(1, 2.2f).
What is operator overloading?
Sbi's famous Operator overloading faq answers this in great detail.
Why are the two function versions in OP allowed to exist?
Notice they take different function parameter types(int and float) and hence qualify as valid function overloads.
What is overload resolution?
It is the process of selecting the most appropriate function/operator by the compiler implementation. If a best viable function exists and is unique, overload resolution succeeds and produces it as the result. Otherwise overload resolution fails and the invocation is treated as ill-formed and compiler provides a diagnostic. The compiler uses implicit conversion sequence to find the best match function.
C++03 Standard 13.3.3.1 Implicit Conversions:
An implicit conversion sequence is a sequence of conversions used to convert an argument in a function call to the type of the corresponding parameter of the function being called.
The implicit conversion sequences can be one of the following categories:
A standard conversion sequence(13.3.3.1.1)
A user-defined conversion sequence(13.3.3.1.2)
An ellipsis conversion sequence(13.3.3.1.3)
Note that each of these are ranked to determine the best viable function. The best viable function is the one all whose parameters have either better or equal-ranked implicit conversion sequences than all of the other viable functions.The standard details each of these in detail in respective sections. The standard conversion sequence is relevant to this case, it is summarized as:
With enough background on overloading resolution.
let us examine the code examples in OP:
function(1.2,2.2);
Important Rule: 1.2 and 2.2 are literals and they are treated as a double data type.
During implicit conversion sequences mapping:
Both the function parameter literals with double type need a conversion rank to either call the float or int version and none is a better match than other, they score exactly the same on conversion rank. The compiler is unable to detect the best viable match and it reports an ambiguity.
function(1.2,2);
During implicit conversion sequence mapping:
One of the function parameters 2 has an exact match with the int function version while another 1.2 has a conversion rank. For function which takes float as parameters the implicit conversion sequences for both parameters are of conversion rank.
So the function which takes int version scores better than the float version and is the best match and gets called.
How to resolve overloading ambiguity errors?
If you don't want the implicit conversion sequence mapping to throw you off, just provide functions and call them in such a way so that the parameters are a exact match. Since exact match scores over all others, You have a definite guarantee of your desired function getting called. In your case there are two ways to do this:
Solution 1:
Call the function so that parameters are exact match to the functions available.
function(1.2f,2.2f);
Since 1.2f and 2.2f are treated as float types they match exactly to the float function version.
Solution 2:
Provide a function overload which exactly matches the parameter type in called function.
function(double, double){}
Since 1.2 and 2.2 are treated as double the called function is exact match to this overload.
If you don't want to (as explained in the accepted answer):
use float literals, e.g. 1.2f
or change the existing float overload to double
You can add another overload that calls the float one:
void function(double y, double w)
{
function((float)y, (float)w);
}
Your code in main now will call the above function, which will call the float overload.
Function overloading in the above example has ambiguous calls because the return type are same and the 2nd argument in the call of function is double, which can be treated as int or float and hence the compiler confuses to which function to execute.
I hope this help
This code is self explaintary for all combination
You need to send two float to call a float function
#include<iostream>
#include<stdio.h>
using namespace std;
//when arguments are both int
void function(int y,int w) {
printf("int function\n");
}
//when arguments are both double
void function(double y, double w) {
printf("double function\n");
}
//when arguments are both float
void function(float y, float w) {
printf("float function\n");
}
//when arguments are int and float
void function(int y, float x) {
printf("int float function\n");
}
//when arguments are float and int
void function(float y,int w) {
printf("float int function\n");
}
//when arguments are int and double
void function(int y, double w) {
printf("int double function\n");
}
//when arguments are double and int
void function(double y, int x) {
printf("double int function\n");
}
//when arguments are double and float
void function(double y, float x) {
printf("double float function\n");
}
//when arguments are float and double
void function(float y, double x) {
printf("float double function\n");
}
int main(int argc, char *argv[]) {
function(1.2,2.2);
function(1.2f,2.2f);
function(1,2);
function(1.2,2.2f);
function(1.2f,2.2);
function(1,2.2);
function(1,2.2f);
function(1.2,2);
function(1.2f,2);
return 0;
}
When sending a primitive type to a function as argument, if the primitive type you are sending is not exactly the same as it requests, you should always cast it to the requested primitive type.
int main()
{
function(1.3f, 2.4f);
function(1.3f, static_cast<float>(2.4));
function(static_cast<float>(1.3), static_cast<float>(2.4));
function(static_cast<float>(1), static_cast<float>(2));
return 0;
}
By default decimal is considered as double. If you want decimal to be floats you suffix it with f.
In your example when you call function(1.2,2.2) the compiler considers the values you have passed it as double and hence you are getting mismatch in function signature.
function(1.2,1.2) ====> function(double,double)
If you want to retain the function signature you need to use floating point suffix while passing floating point literal.
function(1.2f,1.2f) ====> function(float,float).
If you are more interested in knowing about floating point literals you can refer
Why floating point value such as 3.14 are considered as double by default in MSVC?
Like others have said, you give doubles to your overloaded function which is designed for floats. The overloading itself doesn't have any errors.
Here's the correct use of the overloaded function (notice the 'f'´s right after the numbers):
function(1.0f, 2.0f);
function(1.2,2.2);
Those numbers aren't floats, they are doubles. So this code says:
double p1 = 1.2;
double p2 = 2.2;
void (*fn)(double /*decltype(p1)*/, double /*decltype(p2)*/) = function;
The compiler is now looking a "function" which takes two doubles. There is no exact match. So next it looks for a function which takes an argument that can be cast from doubles. There are two matches.
function(int, int);
function(float, float);
You have several options.
Add an exact match overload.
void function(double, double)
{
printf("double function\n");
}
Use casting.
function(static_cast(1.2), static_cast(2.2));
Call "function" with floats instead of doubles:
function(1.2f, 2.2f);
Try This
#include <iostream>
using namespace std;
void print(int i){
cout << i << endl;
}
void print(float i){
cout << i << endl;
}
int main(){
print(5);
print(5.5f);
return 0;
}
In function overloading when float can conflict with other data type in other same name functions then probably this is way to over come it. I tried it worked.
Just imagine how your arguments would be passed.
If it is passed as 1.2 and 2.2 to the (int,int) function then it would to truncated to 1 and 2.
If it is passed as 1.2 and 2.2 to the (float,float) it will be processed as is.
So here is where the ambiguity creeps in.
I have found two ways to solve this problem.
First is the use of literals:-
int main()
{
function(1.2F,2.2F);
return 0;
}
Secondly, and the way I like to do it, It always works (and can also be used for C++'s default conversion and promotion).
For int:-
int main()
{
int a=1.2, b=2.2;
function(a,b);
return 0;
}
For Float:-
int main()
{
float a=1.2, b=2.2;
function(a,b);
return 0;
}
So instead of using actual DIGITS. It is better to declare them as a type first, then overload!
See now, if you send it as (1.2,2) or (1,2.2) then compiler can simply send it to the int function and it would work.
However, to send it to the float function the compiler would have to promote 2 to float. Promotion only happens when no match is found.
Refer:-
Computer Science with C++
Sumita Arora
Chapter: Function Overloading

error when trying to run an overloaded function with float parameters.

I am trying to create a simple (absolute) function in c++, I have created two functions with the same name one that takes an integer and returns an integer and one that takes a float and returns a float but every time I try to run the code I receive this error:
"error: call of overloaded 'absolute(double)' is ambiguous"
I tried changing the input parameters of the second function so that it takes a double and returns a float and the code ran perfectly, I'd like to know why the code won't run when the parameters and return type are both set to float, thank you.
#include <iostream>
#include <fstream>
using namespace std;
int absolute(int x){
if (x<0){
x=-x;
}
return x;
}
float absolute (float x)
{
if (x<0){
x=-x;
}
return x;
}
int main( )
{
cout << absolute(3.5);
}
The type of the literal 3.5 is double, not float.
Choosing either of the overloads would require a conversion. Hence the ambiguity.
You can use 3.5f to make it a float literal.
cout << absolute(3.5f);
A better solution, IMO, would be to use a function template.
template <typename T>
T absolute(T x)
{
return (x < 0 ? -x : x);
}
Read that error message again. Notice how it says double as the argument type it want to use.
That's because floating point constants like 3.5 are of type double. And the compiler don't know if it should convert the double value to an int or a float, thereby giving you the error.
If you want to call the float overload, use 3.5f to make it a float value. Or change your overload to use type double instead of float.
you write that 3.5 is a float this value is not a float it is a double.

Error "double** to double*" while passing pointer in a function c/c++

I have a function that takes a double *result. I am aware that pointers need to be passed by reference in a function. When I call the function void ComputeSeriesPointer(double x, int n, double *result); in main with ComputeSeriesPointer(x, n, &result);, I get the error:
cannot convert ‘double**’ to ‘double*’ for argument ‘3’ to ‘void ComputeSeriesPointer(double, int, double*)’
ComputeSeriesPointer(x, n, &result);
^
When working with pointers, aren't they all passed using the & key? The in class examples were all done this way. Even on the internet things were done this way. Any explanation/clarification would be great.
I am also running this with a c++ compiler (as instructed by my professor) because I am using the pow function.
I'm not sure about what you are doing without seeing the complete code, but If you are doing something like this:
void ComputeSeriesPointer(double, int, double*){
// ...
}
int main(){
double *x = ...;
ComputeSeriesPointer(1.0, 1, &x);
// ...
return 0;
}
Then, the problem is the &x. The & operator is used to extract a variable address. In this case, your variable is already a pointer, so writing &x you are getting a "pointer to pointer", in other words, a double**. That's your problem. Call your function in this way: ComputeSeriesPointer(1.0, 1, x)
The function is expecting you to pass the memory address of an actual double variable, not the memory address of a double* pointer variable:
double result; // NOT double*!
ComputeSeriesPointer(x, n, &result);
You can also do this:
double result; // NOT double*!
double *presult = &result;
ComputeSeriesPointer(x, n, presult);
The error message implies that the type of result is already double *. You don't need to use the & operator if the variable is already a pointer of the appropriate type. So you should do
ComputeSeriesPointer(x, n, result);
Either that, or you need to change the declaration of the result variable in the caller from double * to double.
It is likely that you are doing this:
double *myNewResult;
...
ComputeSeriesPointer(x, n, &myNewResult);
By doing this you are passing the address of a double* not double. You dont need double *myNewResult, just double myNewResult. Or if you need myNewResult to be a double* you can just pass it to the function like this:
ComputeSeriesPointer(x, n, myNewResult);
The function is declared like
void ComputeSeriesPointer(double, int, double*);
its third parameter has type double *
But you call the function like
ComputeSeriesPointer(x, n, &result);
where the third argument has type double **
You need to call the function like
ComputeSeriesPointer(x, n, result);
Or change the function declaration and correspondingly its definition such a way that the third parametr had type double **
void ComputeSeriesPointer(double, int, double **);
Passing a pointer into a function is passing by reference; the pointer is the "reference." (C++ muddied waters a little bit by also introducing a "reference" type which pretends it is not a pointer, but that's not relevant to the code example you've given.)
The & operator means "address of." It takes a thing and returns a pointer to that thing. So,
double x = 1; // this is a double
double *pointer_to_x = &x;
double **pointer_to_pointer_to_x = &pointer_to_x;
and so on.
We need to see a little bit more of your code calling ComputeSeriesPointer() to answer properly, but my guess is that you have:
double *result; // this kind of variable stores *the address of* a double-precision number.
ComputeSeriesPointer( x, n, &result );
but you really want:
double result; // this kind of variable stores a double-precision number.
ComputeSeriesPointer( x, n, &result );
so that you are passing in the address that you want ComputeSeriesPointer() to write a result into.

Strange ambiguous call to overloaded function error

I'm trying
void function(int y,int w)
{
printf("int function");
}
void function(float y,float w)
{
printf("float function");
}
int main()
{
function(1.2,2.2);
return 0;
}
I get an error error like..
error C2668: 'function' : ambiguous call to overloaded function
and when I try to call function(1.2,2) or function(1,2.2) it is printing as "int function"
Please clarify when will the function(float y,float w) be called?
Look at the error message from gcc:
a.cpp:16: error: call of overloaded ‘function(double, double)’ is ambiguous
a.cpp:3: note: candidates are: void function(int, int)
a.cpp:9: note: void function(float, float)
A call to either function would require truncation, which is why neither is preferred over the other. I suspect you really want void function(double y,double w). Remember that in C/C++, the default floating-point type for literals and parameter passing is double, NOT float.
UPDATE
If you really don't want to change the function signature from float to double, you can always use literals that are typed as float. If you add the suffix f to the floating point numbers, they will be typed float.
Your examples would then be function(1.2f, 2f) and function(1, 2.2f).
What is operator overloading?
Sbi's famous Operator overloading faq answers this in great detail.
Why are the two function versions in OP allowed to exist?
Notice they take different function parameter types(int and float) and hence qualify as valid function overloads.
What is overload resolution?
It is the process of selecting the most appropriate function/operator by the compiler implementation. If a best viable function exists and is unique, overload resolution succeeds and produces it as the result. Otherwise overload resolution fails and the invocation is treated as ill-formed and compiler provides a diagnostic. The compiler uses implicit conversion sequence to find the best match function.
C++03 Standard 13.3.3.1 Implicit Conversions:
An implicit conversion sequence is a sequence of conversions used to convert an argument in a function call to the type of the corresponding parameter of the function being called.
The implicit conversion sequences can be one of the following categories:
A standard conversion sequence(13.3.3.1.1)
A user-defined conversion sequence(13.3.3.1.2)
An ellipsis conversion sequence(13.3.3.1.3)
Note that each of these are ranked to determine the best viable function. The best viable function is the one all whose parameters have either better or equal-ranked implicit conversion sequences than all of the other viable functions.The standard details each of these in detail in respective sections. The standard conversion sequence is relevant to this case, it is summarized as:
With enough background on overloading resolution.
let us examine the code examples in OP:
function(1.2,2.2);
Important Rule: 1.2 and 2.2 are literals and they are treated as a double data type.
During implicit conversion sequences mapping:
Both the function parameter literals with double type need a conversion rank to either call the float or int version and none is a better match than other, they score exactly the same on conversion rank. The compiler is unable to detect the best viable match and it reports an ambiguity.
function(1.2,2);
During implicit conversion sequence mapping:
One of the function parameters 2 has an exact match with the int function version while another 1.2 has a conversion rank. For function which takes float as parameters the implicit conversion sequences for both parameters are of conversion rank.
So the function which takes int version scores better than the float version and is the best match and gets called.
How to resolve overloading ambiguity errors?
If you don't want the implicit conversion sequence mapping to throw you off, just provide functions and call them in such a way so that the parameters are a exact match. Since exact match scores over all others, You have a definite guarantee of your desired function getting called. In your case there are two ways to do this:
Solution 1:
Call the function so that parameters are exact match to the functions available.
function(1.2f,2.2f);
Since 1.2f and 2.2f are treated as float types they match exactly to the float function version.
Solution 2:
Provide a function overload which exactly matches the parameter type in called function.
function(double, double){}
Since 1.2 and 2.2 are treated as double the called function is exact match to this overload.
If you don't want to (as explained in the accepted answer):
use float literals, e.g. 1.2f
or change the existing float overload to double
You can add another overload that calls the float one:
void function(double y, double w)
{
function((float)y, (float)w);
}
Your code in main now will call the above function, which will call the float overload.
Function overloading in the above example has ambiguous calls because the return type are same and the 2nd argument in the call of function is double, which can be treated as int or float and hence the compiler confuses to which function to execute.
I hope this help
This code is self explaintary for all combination
You need to send two float to call a float function
#include<iostream>
#include<stdio.h>
using namespace std;
//when arguments are both int
void function(int y,int w) {
printf("int function\n");
}
//when arguments are both double
void function(double y, double w) {
printf("double function\n");
}
//when arguments are both float
void function(float y, float w) {
printf("float function\n");
}
//when arguments are int and float
void function(int y, float x) {
printf("int float function\n");
}
//when arguments are float and int
void function(float y,int w) {
printf("float int function\n");
}
//when arguments are int and double
void function(int y, double w) {
printf("int double function\n");
}
//when arguments are double and int
void function(double y, int x) {
printf("double int function\n");
}
//when arguments are double and float
void function(double y, float x) {
printf("double float function\n");
}
//when arguments are float and double
void function(float y, double x) {
printf("float double function\n");
}
int main(int argc, char *argv[]) {
function(1.2,2.2);
function(1.2f,2.2f);
function(1,2);
function(1.2,2.2f);
function(1.2f,2.2);
function(1,2.2);
function(1,2.2f);
function(1.2,2);
function(1.2f,2);
return 0;
}
When sending a primitive type to a function as argument, if the primitive type you are sending is not exactly the same as it requests, you should always cast it to the requested primitive type.
int main()
{
function(1.3f, 2.4f);
function(1.3f, static_cast<float>(2.4));
function(static_cast<float>(1.3), static_cast<float>(2.4));
function(static_cast<float>(1), static_cast<float>(2));
return 0;
}
By default decimal is considered as double. If you want decimal to be floats you suffix it with f.
In your example when you call function(1.2,2.2) the compiler considers the values you have passed it as double and hence you are getting mismatch in function signature.
function(1.2,1.2) ====> function(double,double)
If you want to retain the function signature you need to use floating point suffix while passing floating point literal.
function(1.2f,1.2f) ====> function(float,float).
If you are more interested in knowing about floating point literals you can refer
Why floating point value such as 3.14 are considered as double by default in MSVC?
Like others have said, you give doubles to your overloaded function which is designed for floats. The overloading itself doesn't have any errors.
Here's the correct use of the overloaded function (notice the 'f'´s right after the numbers):
function(1.0f, 2.0f);
function(1.2,2.2);
Those numbers aren't floats, they are doubles. So this code says:
double p1 = 1.2;
double p2 = 2.2;
void (*fn)(double /*decltype(p1)*/, double /*decltype(p2)*/) = function;
The compiler is now looking a "function" which takes two doubles. There is no exact match. So next it looks for a function which takes an argument that can be cast from doubles. There are two matches.
function(int, int);
function(float, float);
You have several options.
Add an exact match overload.
void function(double, double)
{
printf("double function\n");
}
Use casting.
function(static_cast(1.2), static_cast(2.2));
Call "function" with floats instead of doubles:
function(1.2f, 2.2f);
Try This
#include <iostream>
using namespace std;
void print(int i){
cout << i << endl;
}
void print(float i){
cout << i << endl;
}
int main(){
print(5);
print(5.5f);
return 0;
}
In function overloading when float can conflict with other data type in other same name functions then probably this is way to over come it. I tried it worked.
Just imagine how your arguments would be passed.
If it is passed as 1.2 and 2.2 to the (int,int) function then it would to truncated to 1 and 2.
If it is passed as 1.2 and 2.2 to the (float,float) it will be processed as is.
So here is where the ambiguity creeps in.
I have found two ways to solve this problem.
First is the use of literals:-
int main()
{
function(1.2F,2.2F);
return 0;
}
Secondly, and the way I like to do it, It always works (and can also be used for C++'s default conversion and promotion).
For int:-
int main()
{
int a=1.2, b=2.2;
function(a,b);
return 0;
}
For Float:-
int main()
{
float a=1.2, b=2.2;
function(a,b);
return 0;
}
So instead of using actual DIGITS. It is better to declare them as a type first, then overload!
See now, if you send it as (1.2,2) or (1,2.2) then compiler can simply send it to the int function and it would work.
However, to send it to the float function the compiler would have to promote 2 to float. Promotion only happens when no match is found.
Refer:-
Computer Science with C++
Sumita Arora
Chapter: Function Overloading

C++ help with error : cannot convert parameter 1 from 'float' to 'float [][2]

and I was doing a program, that isn't so important. Apparently, I cant send parameters to a float function.
the code look something like this
float myfunction(float array[1][2])
{
// ...
return 0;
}
int main()
{
float array[1][2];
int foo = 0;
// assigning values to the array
foo = myfunction(array[1][2]);
return 0;
}
when I try to compile, I get the error "cannot convert parameter 1 from 'float' to 'float [][2]"
What is wrong? And how can I solve it?
Just pass array, without the indexes:
foo = myfunction(array);
A couple of things.
First, a function prototyped float myfunction(float array[1][2]) is confusing (you), since what it actually mean is: float myfunction(float array[][2]) or float myfunction(float (*array)[2]). The function accepts a pointer to (one or more) array(s) of two floats.
Second, the error you get is because the function accepts a pointer to an array, while you're tryinmg to pass it single float - element [1][2] of the two-dimensional array float array[1][2]. Perhaps you meant to pass the entire array to the function?
You've defined the variable: float array[1][2];
Then, you call the function in this way: foo = myfunction(array);
As a parameter, only you have to set the variable name. You shouldn't do this: foo = myfunction(array[1][2]);
When you make a function, do it in this way: type myfunction(float Array[][w]) , being type the type of function (void, float...) and "w" a constant integer.
You are passing a certain cell and not the array