Given the following member function overload to take various functors
class Foo {
public:
void bar(boost::function<void(int)> func);
void bar(boost::function<void(float)> func);
void bar(boost::function<void(const std::vector<float>&)> func);
}
and the function
void baz(float f) { std::cout << "float :" << f << std::endl; }
then why does taking the plain function pointer of baz
Foo foo;
foo.bar(&baz);
yield this error:
error: call of overloaded ‘bar(void (*)(float))’ is ambiguous
note: candidates are: void Foo::bar(boost::function<void(int)>)
note: void Foo::bar(boost::function<void(float)>)
note: void Foo::bar(boost::function<void(const std::vector<float, std::allocator<float> >&)>)
How to resolve this ambiguity ?
Not pretty and not safe:
foo.bar( static_cast<function<void(float)> >( &baz ) );
Another alternative: use Initializers.
foo.bar( function<void(float)>{ &baz } );
Related
I have a list of function pointers, the non-class member compiles without errors, but the class member compiles with errors:
error: cannot convert 'void (CVdmConfig::)()' to 'fp {aka void ()()}' in initialization
CVdmConfig::writeConfig is a void function.
typedef void (*fp)();
fp fpList[] = {&valvesCalib,&CVdmConfig::writeConfig} ;
What do I wrong ?
best regards
Werner
Without seeing the rest of your code, there is not much I can debug, but here is an example that works:
#include <iostream>
using namespace std;
void valvesCalib() {
cout << "inside function\n";
}
class CVdmConfig {
public:
static void writeConfig() {
cout << "inside method\n";
}
};
typedef void (*fp)();
fp fpList[] = {
&valvesCalib,
&CVdmConfig::writeConfig
};
int main()
{
for (auto f: fpList) {
f();
}
return 0;
}
/*
Output:
inside function
inside method
Program finished with exit code 0
*/
The problem was the missing static definition in the member function. But this leads into other problems with variables in the class. So I use a wrapper for this.
I am trying to build a class that stores a user-defined function inside of it for later use. I have decided to use the boost::function object to do so.
However, I get the following error on compile:
error: no match for ‘operator=’ in ‘((SomeClass*)this)->SomeClass::someFunction = ((SomeClass*)this)->SomeClass::DefaultFunction’
I do not understand this error, since someFunction and DefaultFunction should, as far as I can see, have the same types.
The code is shown below:
#include <boost/function.hpp>
class SomeClass{
private:
boost::function<int(int)> someFunction;
int DefaultFunction(int i);
public:
SomeClass();
~SomeClass();
void SetFunction(int (*f)(int));
};
int SomeClass::DefaultFunction(int i){
return i+1;
}
SomeClass::SomeClass(){
someFunction=DefaultFunction;
}
~SomeClass::SomeClass(){
}
void SomeClass::SetFunction(int (*f)(int i)){
someFunction=f;
}
void MyProgram(){
SomeClass s;
}
Can anyone offer any pointers as to how to construct such an object? Alternatively, iff there is a better way than the one I am attempting, could you explain it to me?
Kindest regards!
DefaultFunction is a member function of SomeClass.
Member function is called for some instance of SomeClass.
This function takes "hidden" pointer to SomeClass instance as its first parameter addition to int.
So member function is not the same as free function.
Your someFunction is object of boost::function, so it is wrapper for callable object.
Your requirements to that object are: take int and returns int.
In order to assign DefaultFunction (as member function) to someFunction you need to create this callable object.
Here you need to specify for which instance of SomeClass this object will be called, to do that use boost::bind:
SomeClass::SomeClass(){
someFunction=boost::bind(&SomeClass::DefaultFunction, this, boost::placeholders::_1);
}
In the code above you create callable object which will behave as
struct unnamedClass {
SomeClass* sc;
unnamedClass (SomeClass* sc) : sc(sc) {} // here sc is this of SomeClass
int operator()(int arg)
{
return sc->DefaultFunction(arg);
}
};
so when you invoke someFunction(10) it takes 10 as argument and call DefaultFunction for current this instance.
This
void SomeClass::SetFunction(int (*f)(int i)){
someFunction=f;
}
works because f is free function, which takes no hidden - pointer to class instance.
Using the answer of #rafix07, the following code compiled:
#include <iostream>
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <boost/bind/placeholders.hpp>
class SomeClass{
private:
public:
SomeClass();
~SomeClass();
boost::function<int(int)> someFunction;
int DefaultFunction(int i);
void SetFunction(int (*f)(int));
};
int SomeClass::DefaultFunction(int i){
return i+1;
}
SomeClass::SomeClass(){
someFunction=boost::bind(&SomeClass::DefaultFunction, this, _1);
}
SomeClass::~SomeClass(){
}
void SomeClass::SetFunction(int (*f)(int i)){
someFunction=f;
}
int MyOwnProgram(int i){
return i+2;
}
void MyProgram(){
SomeClass s;
std::cout<<s.someFunction(2)<<std::endl;
s.SetFunction(MyOwnProgram);
std::cout<<s.someFunction(2)<<std::endl;
}
int main()
{
MyProgram();
}
The output from the program is:
3
4
In iterable.dart file, code for forEach is:
void forEach(void f(E element)) {
for (E element in this) f(element);
}
You can see, forEach parameter accepts a method and its return type should be void but following code just works fine without any error:
var list = [1, 2, 3];
list.forEach((item) {
print(item);
return true; // should show an error
});
The callback you pass to forEach() would be inferred as a bool Function(int), and List<int>.forEach() expects a void Function(int). This is accepted since T Function() is considered a subtype of void Function(); T Function() is substitutable anywhere void Function() is used.
I think in dart when you use the void return type with a function , the return type could be void or anything else
for example :
main()=>print(function() as int); // the output is 12
void function()=>12;
in this example the void function returns a value
example 2:
class Super {
void function(){}
}
class Child extends Super{
#override
int function(){
return 10;
}
you can override a function that have a type of void and change the type of the function to anything else.
I have a main class:
class Sportist{
private:
string ime;
int godina_na_ragjanje;
int godisna_zarabotuvacka_EUR;
public:
Sportist(string i, int g_n_r, int g_z_EUR){
ime = i;
godina_na_ragjanje = g_n_r;
godisna_zarabotuvacka_EUR = g_z_EUR;
}
};
And now I have a new class like this:
class Fudbaler:public Sportist{
private:
int broj_na_odigrani_natprevari;
int danocna_stapka;
public:
Fudbaler(string ime, int godina, int zarabotuvacka, int b, int d){
:Sportist(ime, godina, zarabotuvacka)
broj_na_odigrani_natprevari = b;
danocna_stapka = d;
}
float danok(){
return godisna_zarabotuvacka_EUR * danocna_stapka;
}
friend ostream& operator<<(ostream &os, Fudbaler F){
return os << "Ime: " << ime << endl
<< "Godina na raganje: " << godina_na_ragjanje << endl
<< "Godisna zarabotuvacka(EUR): " << godisna_zarabotuvacka_EUR << endl
<< "Danok sto treba da plati: " << danok();
}
};
I want to call the constructor from the first class in the second class, but I get errors that I haven't provided arguments which I do.. and also, I want to know how to access the private elements from the first class in the second, because it's taken as 'public', so how can I use them in my functions, like danok().
Errors while calling the constructor:
no matching function for call to 'Sportist::Sportist()'
candidates are:
Sportist::Sportist(std::string, int, int)
candidate expects 3 arguments, 0 provided
Error while calling variables using public method:
'int Sportist::godisna_zarabotuvacka_EUR' is private
You do not initialize Sportist before you enter your Fudbaler constructor function body. Therefore the Compiler tries to use a default constructur of Sportist which does not exists.
You Need to initialize Sportist before entering the Fudbaler constructor body.
Initializers are appended after the closing parenthesis before the function body in curly brackets:
Fudbaler(string ime, int godina, int zarabotuvacka, int b, int d)
: Sportist(ime, godina, zarabotuvacka),
broj_na_odigrani_natprevari(b),
danocna_stapka(d)
{
}
Private variables are private and cannot be accessed in child classes.
If you want to Access the Sportist members in Fudbaler member function you need to declare them protected (only accessible in this class and child classes) or public (generally accessible).
I have read the description, and I understand that it is a function-type alias.
A typedef, or function-type alias, gives a function type a name that you can use when declaring fields and return types. A typedef retains type information when a function type is assigned to a variable.
http://www.dartlang.org/docs/spec/latest/dart-language-specification.html#kix.yyd520hand9j
But how do I use it? Why declaring fields with a function-type? When do I use it? What problem does it solve?
I think I need one or two real code examples.
A common usage pattern of typedef in Dart is defining a callback interface. For example:
typedef void LoggerOutputFunction(String msg);
class Logger {
LoggerOutputFunction out;
Logger() {
out = print;
}
void log(String msg) {
out(msg);
}
}
void timestampLoggerOutputFunction(String msg) {
String timeStamp = new Date.now().toString();
print('${timeStamp}: $msg');
}
void main() {
Logger l = new Logger();
l.log('Hello World');
l.out = timestampLoggerOutputFunction;
l.log('Hello World');
}
Running the above sample yields the following output:
Hello World
2012-09-22 10:19:15.139: Hello World
The typedef line says that LoggerOutputFunction takes a String parameter and returns void.
timestampLoggerOutputFunction matches that definition and thus can be assigned to the out field.
Let me know if you need another example.
Dart 1.24 introduces a new typedef syntax to also support generic functions. The previous syntax is still supported.
typedef F = List<T> Function<T>(T);
For more details see https://github.com/dart-lang/sdk/blob/master/docs/language/informal/generic-function-type-alias.md
Function types can also be specified inline
void foo<T, S>(T Function(int, S) aFunction) {...}
See also https://www.dartlang.org/guides/language/language-tour#typedefs
typedef LoggerOutputFunction = void Function(String msg);
this looks much more clear than previous version
Just slightly modified answer, according to the latest typedef syntax, The example could be updated to:
typedef LoggerOutputFunction = void Function(String msg);
class Logger {
LoggerOutputFunction out;
Logger() {
out = print;
}
void log(String msg) {
out(msg);
}
}
void timestampLoggerOutputFunction(String msg) {
String timeStamp = new Date.now().toString();
print('${timeStamp}: $msg');
}
void main() {
Logger l = new Logger();
l.log('Hello World');
l.out = timestampLoggerOutputFunction;
l.log('Hello World');
}
Typedef in Dart is used to create a user-defined function (alias) for other application functions,
Syntax: typedef function_name (parameters);
With the help of a typedef, we can also assign a variable to a function.
Syntax:typedef variable_name = function_name;
After assigning the variable, if we have to invoke it then we go as:
Syntax: variable_name(parameters);
Example:
// Defining alias name
typedef MainFunction(int a, int b);
functionOne(int a, int b) {
print("This is FunctionOne");
print("$a and $b are lucky numbers !!");
}
functionTwo(int a, int b) {
print("This is FunctionTwo");
print("$a + $b is equal to ${a + b}.");
}
// Main Function
void main() {
// use alias
MainFunction number = functionOne;
number(1, 2);
number = functionTwo;
// Calling number
number(3, 4);
}
Output:
This is FunctionOne
1 and 2 are lucky numbers !!
This is FunctionTwo
3 + 4 is equal to 7
Since dart version 2.13 you can use typedef not only with functions but with every object you want.
Eg this code is now perfectly valid:
typedef IntList = List<int>;
IntList il = [1, 2, 3];
For more details see updated info:
https://dart.dev/guides/language/language-tour#typedefs
https://www.tutorialspoint.com/dart_programming/dart_programming_typedef.htm
typedef ManyOperation(int firstNo , int secondNo); //function signature
Add(int firstNo,int second){
print("Add result is ${firstNo+second}");
}
Subtract(int firstNo,int second){
print("Subtract result is ${firstNo-second}");
}
Divide(int firstNo,int second){
print("Divide result is ${firstNo/second}");
}
Calculator(int a,int b ,ManyOperation oper){
print("Inside calculator");
oper(a,b);
}
main(){
Calculator(5,5,Add);
Calculator(5,5,Subtract);
Calculator(5,5,Divide);
}