Reputation: 4995
Why can a function like this
typedef std::vector<someclass> infocontainer;
double function2(const infocontainer&);
void function1(std::ostream&, const std::string&, double function2(const infocontainer&), const infocontainer, const infocontainer);
when called in main runs fine
function1(std::cout, "astring", function2, did, didnt);
But when function2 has a second argument it produces an error.
double function2(const infocontainer&, std::string&);
void function1(std::ostream&, const std::string&, double function2(const infocontainer&, const std::string&), const infocontainer, const infocontainer);
main
function1(std::cout, "astring", function2, did, didnt);
candidate function not viable: no known conversion from 'double (const infocontainer &, const
std::string &)' to 'double (*)(const infocontainer &, std::string &)' for 3rd argument
Upvotes: 0
Views: 349
Reputation: 57678
typedef
is your friend with function pointers.
The typedef
will reduce a lot of problems especially when specifying parameters for a function.
typedef double (*Pointer_To_One_Argument_Function)(const infocontainer&);
typedef double (*Pointer_To_Two_Argument_Function)(const infocontainer&, std::string&);
void function1A(std::ostream&, const std::string&, Pointer_To_One_Argument_Function, const infocontainer, const infocontainer);
void function1B(std::ostream&, const std::string&, Pointer_To_Two_Argument_Function, const infocontainer, const infocontainer);
In the above example, the typedef
can make the declarations more readable.
Also, changing the type of the parameter is easier should you choose to change the number or types of the parameters for the function pointer.
As for your question, examine the syntax of the function pointer in your two parameter function pointer example.
Rather than using the complex or complicated syntax for a function pointer, the C++ language offers another alternative: Function objects.
A function object is a class
or struct
that has an overloaded operator()
.
Example:
struct Function_Object_One_Parameter
{
virtual double operator()(const infocontainer&) = 0;
};
struct Function_Object_Two_Parameter
{
virtual double operator()(const infocontainer&, std::string&) = 0;
};
void function1C(std::ostream&, const std::string&, Function_Object_One_Parameter& f1, const infocontainer ic, const infocontainer)
{
// ...
f1(ic);
// ...
}
void function1D(std::ostream&, const std::string& s, Function_Object_Two_Parameter& f2, const infocontainer ic, const infocontainer)
{
// ...
f2(ic, s);
// ...
}
To use this pattern, declare functions derived from Function_Object_One_Parameter
or Function_Object_Two_Parameter
:
struct Happy_Function_One
: public Function_Object_One_Parameter
{
double operator()(const infocontainer&)
{
std::cout << "Happy" << std::endl;
return 3.14159267;
}
}
Upvotes: 1
Reputation: 16761
"no known conversion from"
double (const infocontainer &, const std::string &)
"to"
double (*)(const infocontainer &, std::string &)
The difference is in const
to second argument. You may think that the function is defined as double function2(const infocontainer&, const std::string&);
but your compiler disagrees.
Upvotes: 3
Reputation: 672
Because the code you have posted is not the same that the code you are trying to compile.
The following line
void function1(std::ostream&, const std::string&, double function2(const infocontainer&, const std::string&), const infocontainer, const infocontainer);
is missing a const
before std::string &
in the third parameter in the code you are trying to compile.
Upvotes: 1