I have tried multiple google searches and help guides, but I'm out of ideas on this one. I have a function pointer that I am using as an argument for another function. Both functions are within the same class. However, I keep getting type conversion errors. I'm sure this is just a syntax problem, but I can't understand what the correct syntax is. Here is a simplified version of my code:
Header File
#ifndef T_H
#define T_H
#include <iostream>
#include <complex>
namespace test
{
class T
{
public:
T();
double Sum(std::complex<double> (*arg1)(void), int from, int to);
int i;
std::complex<double> func();
void run();
};
}
#endif // T_H
Source File
#include "t.h"
using namespace test;
using namespace std;
//-----------------------------------------------------------------------
T::T()
{
}
//-----------------------------------------------------------------------
double T::Sum(complex<double>(*arg1)(void), int from, int to)
{
complex<double> out(0,0);
for (i = from; i <= to; i++)
{
out += arg1();
cout << "i = " << i << ", out = " << out.real() << endl;
}
return out.real();
}
//-----------------------------------------------------------------------
std::complex<double> T::func(){
complex<double> out(i,0);
return out;
}
//-----------------------------------------------------------------------
void T::run()
{
Sum(&test::T::func, 0, 10);
}
Whenever I try to compile, I get the following error:
no matching function for call to 'test::T::Sum(std::complex<double> (test::T::*)(),int,int)'
note: no known conversion for argument 1 from 'std::complex<double> (test::T::*)()' to 'std::complex<double>(*)()'
Any advice appreciated. Or at least a link to a thorough site on how to use function pointers. I am using Qt Creator 2.6.2, compiling with GCC.
Your Sum function expects pointer to a function. And then you try to call it with a pointer to a member function. Learn about pointers to members.
The code itself is a bit messy, I'll only correct the grammer to make it work.
firstly, you shall change the function prototype from
double Sum(std::complex<double> (*arg1)(void), int from, int to);
to
double Sum(std::complex<double> (T::*arg1)(void), int from, int to);
Meaning that it is a pointer to class T's member.
Then, when calling the function, you cant just arg1(),
for (i = from; i <= to; i++)
{
out += arg1();
cout << "i = " << i << ", out = " << out.real() << endl;
}
you have to use (this->*arg1)();
for (i = from; i <= to; i++)
{
out += (this->*arg1)();
cout << "i = " << i << ", out = " << out.real() << endl;
}
How to pass functions as arguments in C++? In general, use a template, unless you have very compelling reasons not do it.
template<typename Func>
void f(Func func) {
func(); // call
}
On the call side, you can now throw in a certain amount of objects (not just pointers to functions):
Functors;
struct MyFunc {
void operator()() const {
// do stuff
}
};
// use:
f(MyFunc());
Plain functions:
void foo() {}
// use
f(&foo) {}
Member functions:
struct X {
void foo() {}
};
// call foo on x
#include <functional>
X x;
func(std::bind(&X::foo, x));
Lambdas:
func([](){});
If you really want a compiled function and not a template, use std::function:
void ff(std::function<void(void)> func) {
func();
}
Related
I am attempting to create a wrapper around class functions. The purpose of my wrapper is to test input, output, and enforce order of operations with various calls throughout my program. I am trying to not make any changes to the callee class. Attached is an example of what I am trying to achieve, but unable to figure out.
Main.cpp
#include "func_warpper.h"
#include "func.h"
int main()
{
func_wrapper fw
fun func;
int origValue = 5;
fw.caller([&](int origValue) { func.f(origValue); }, origValue);
int output = func.getResult().number;
std::cout << " value outputed by function 2 : " << output << std::endl;
// output
// note that above line does give me the result I am looking for
// however, I want to be able to get this inside the function of caller
return 0;
}
func.h .... I want this to be unmodified
#ifndef FUN_H
#define FUN_H
class fun
{
public:
struct result
{
int number;
};
fun();
~fun();
void f(int value);
struct result getResult(){return this->testResult;};
private:
struct result testResult;
};
#endif
func.cpp .... I want this to be unmodified
#include "func.h"
fun::fun(){
this->testResult.number = 0;
return;
}
fun::~fun(){
return;
}
void fun::f(int value){
int updateValue = value * 5;
this->testResult.number = updateValue;
}
func_wrapper.h .... I can modify this until the cows come home, please go ham with recommended changes :)
class func_wrapper
{
public:
struct new_result
{
int new_number;
};
func_wrapper();
~func_wrapper();
void caller(std::function<void(int)> clb, int val);
struct new_result getNewResult() { return this->new_testResult; };
private:
struct new_result new_testResult;
};
#endif
func_wrapper.cpp .... same as above, I can modify this until the cows come home, please go ham with recommended changes :)
#include "func_wrapper.h"
func_wrapper::func_wrapper()
{
//ctor
this->new_testResult.new_number = 0;
return;
}
func_wrapper::~func_wrapper()
{
//dtor
}
void func_wrapper::caller(std::function<void(int)> clb, int val)
{
std::cout << " value entered into function: " << val << std::endl;
// clb(val); seems to call the function but does not store locally anything
clb(val);
clb;
// clb; seems to store all the information locally however I seem unable to
// to reach the infromation: clb -> [functor] -> func -> testResult -> number
// would like ...
int output = clb ??? // the result of what gets filled from number struct
// if I attempt to #include func.h
// func func;
// func.getResult().number; locally the answer is zero with or without delay
}
Through several days of searching, I have not found anything that can help with this problem, to include similar enough questions on stack overflow. Any help would be greatly appreciated, thank you.
So, my understanding is that inside func_wrapper::caller you want to be able to access the wrapped class that is inside your callback. Unfortuately, the way you are doing it, is impossible. There is no (legitimate) way to reach inside the function and access its arguments.
However, if you break up the operation into its component parts, you can do what you want. You would want a caller function more like this:
template <typename Type, typename Function>
void caller(Type&& functor, Function function, int val)
{
std::cout << " value entered into function: " << val << std::endl;
std::invoke(function, functor, val);
std::cout << "value inside wrapper: " << functor.getResult().number << "\rn";
}
and then call it like this.
fw.caller(func, &fun::f, origValue);
https://godbolt.org/z/151YfEeoo
#JohnFilleau had mentioned to pass the class object instead of the function from within the class. The following is the solution based on example code that he provided, and I modified to work with the example. I realize the question is confusing but would like to thank both JohnFilleau and Taekahn for the discussion.
In main.cpp
int main()
{
func_wrapper fw;
fun func;
int origValue = 5;
fw.caller2(func, origValue);
return 0:
}
func_wrapper::caller2
void func_wrapper::caller2(fun& fun, int val)
{
std::cout << " value entered into function: " << val << std::endl;
fun.f(val);
int output = fun.getResult().number;
std::cout << " did this work: " << output << std::endl;
}
In the header I had to add
#include "func.h"
with the change to the header as follows
void caller2(fun& fun, int val);
I have the following code:
#include<iostream>
using namespace std;
void saludo();
void despedida();
int main(){
void (*Ptr_Funciones[2])() = {saludo, despedida};
(Ptr_Funciones[0])();
(Ptr_Funciones[1])();
return 0;
}
void saludo(){
cout<<"\nHola mundo";
}
void despedida(){
cout<<"\nAdios mundo"<<endl<<endl;
}
Based on this, a few questions were generated which I investigated before asking but did not fully understand.
The questions are:
How do I make an array of functions, if they are of a different type?
I know that in C ++ this notation is used for undetermined parameters: (type var ...) The
thing is, I don't know how to interact with them inside the function.
If questions 1 and 2 are possible, can these points be combined when creating function
arrays?
I really have investigated. But I can't find much information, and the little I did find I didn't understand very well. I hope you can collaborate with me.
Thank you very much.
How do I make an array of functions, if they are of a different type?
You can, but you don't want to. It doesn't make semantic sense. An array is a collection of the same kind of thing. If you find that you need to make a collection of different kinds of things, there are several data structures at your disposal.
I know that in C++ this notation is used for undetermined parameters: (type var ...) The thing is, I don't know how to interact with them inside the function.
Here's how you can use the syntax you mention. They're called variadic functions.
If questions 1 and 2 are possible, can these points be combined when creating function arrays?
Erm, I can't imagine why/when a combination of these two would be needed, but out of intellectual curiosity, awayyy we go...
A modified version of the code from the reference link above that kinda does what you want (i've used a map instead of an array, cuz why not):
#include <iostream>
#include <cstdarg>
#include <unordered_map>
template<typename T>
using fooptr = void (*) (T *t...);
struct A {
const char *fmt;
A(const char *s) :fmt{s} {}
};
struct B : public A {
B(const char *s) : A{s} {}
};
void simple_printf(A *a...)
{
va_list args;
auto fmt = a->fmt;
va_start(args, a);
while (*fmt != '\0') {
if (*fmt == 'd') {
int i = va_arg(args, int);
std::cout << i << '\n';
} else if (*fmt == 'c') {
// note automatic conversion to integral type
int c = va_arg(args, int);
std::cout << static_cast<char>(c) << '\n';
} else if (*fmt == 'f') {
double d = va_arg(args, double);
std::cout << d << '\n';
}
++fmt;
}
va_end(args);
}
int main()
{
A a{"dcff"};
B b{"dcfff"};
std::unordered_map<size_t, fooptr<struct A>> index;
index[1] = simple_printf;
index[5] = simple_printf;
index[1](&a, 3, 'a', 1.999, 42.5);
index[5](&b, 4, 'b', 2.999, 52.5, 100.5);
}
This still really doesn't do what you wanted (i.e., give us the ability to choose from different functions during runtime). Bonus points if you understand why that's the case and/or how to fix it to do what you want.
Use a type alias to make things readable:
Live On Coliru
using Signature = void();
Signature* Ptr_Funciones[] = { saludo, despedida };
Prints
Hola mundo
Adios mundo
More flexible:
You can also use a vector:
Live On Coliru
#include <iostream>
#include <vector>
using namespace std;
void saludo() { cout << "\nHola mundo"; }
void despedida() { cout << "\nAdios mundo" << endl << endl; }
int main() {
vector Ptr_Funciones = { saludo, despedida };
Ptr_Funciones.front()();
Ptr_Funciones.back()();
}
Prints the same.
More Flexibility: Calleables of Different Types
To bind different types of functions, type-erasure should be used. std::function helps:
Live On Coliru
#include <iostream>
#include <functional>
#include <vector>
using namespace std;
void saludo(int value) { cout << "\nHola mundo (" << value << ")"; }
std::string despedida() { cout << "\nAdios mundo" << endl << endl; return "done"; }
int main() {
vector<function<void()>>
Ptr_Funciones {
bind(saludo, 42),
despedida
};
Ptr_Funciones.front()();
Ptr_Funciones.back()();
}
Prints
Hola mundo (42)
Adios mundo
Here is one solution that is possible, whether it fits your needs I'm not sure.
#include <Windows.h>
#include <iostream>
void saludo()
{
std::cout << "\nHola mundo" << std::endl;;
}
void despedida()
{
std::cout << "\nAdios mundo" << std::endl;
}
void* fnPtrs[2];
typedef void* (VoidFunc)();
int main()
{
fnPtrs[0] = saludo;
fnPtrs[1] = despedida;
((VoidFunc*)fnPtrs[0])();
((VoidFunc*)fnPtrs[1])();
std::getchar();
return 0;
}
I stumbled across a strange c++ snippet. I consider this as bad code. Why would someone repeat the function declaration inside a function? It even compiles when changing the type signature to unsigned int sum(int, int) producing the expected result 4294967294j. Why does this even compile?
#include <iostream>
#include <typeinfo>
using namespace std;
int sum(int a, int b){
return a + b;
}
int main()
{
int sum(int, int); // redeclaring sum???
int a = -1;
auto result = sum(a, a);
cout << result << typeid(result).name() << endl;
}
Edit: It compiles for me... but is it valid C++ code? If not why does the compiler (mingw 4.8.1) allow it?
Sometimes there is a sense to redeclare a function inside a block scope. For example if you want to set a default argument. Consider the following code
#include <typeinfo>
using namespace std;
int sum(int a, int b){
return a + b;
}
int main()
{
int sum(int, int = -1 ); // redeclaring sum???
int a = -1;
auto result = sum(a, a);
cout << result << typeid(result).name() << endl;
result = sum(a);
cout << result << typeid(result).name() << endl;
}
Another case is when you want to call a concrete function from a set of overloaded functions. Consider the following example
#include <iostream>
void g( int ) { std::cout << "g( int )" << std::endl; }
void g( short ) { std::cout << "g( short )" << std::endl; }
int main()
{
char c = 'c';
g( c );
{
void g( short );
g( c );
}
}
If that's the actual code, there's no reason to do it.
If the function sum is defined somewhere else though, the declaration inside main makes it accessible only inside main. You can't use it anywhere else in that translation unit (unless of course you declare it). So it's a sort of limiting visibility to where it's needed, but, granted, it's not very readable.
Regarding changing the return type - that's illegal. You're not seeing any issues with unsigned int, but if you try
char sum(int, int); // redeclaring sum???
you'll see there's a problem there.
#include <iostream>
using namespace std;
class B
{
public:
int getMsg(int i)
{
return i + 1;
}
};
class A
{
B b;
public:
void run()
{
taunt(b.getMsg);
}
void taunt(int (*msg)(int))
{
cout << (*msg)(1) << endl;
}
};
int main()
{
A a;
a.run();
}
The above code has a class B inside a class A, and class A has a method taunt that takes a function as an argument. class B's getMsg is passed into taunt...The above code generated the following error message: "error: no matching function for call to 'A::taunt()'"
What's causing the error message in the above code? Am I missing something?
Update:
#include <iostream>
using namespace std;
class B
{
public:
int getMsg(int i)
{
return i + 1;
}
};
class A
{
B b;
public:
void run()
{
taunt(b.getMsg);
}
void taunt(int (B::*msg)(int))
{
cout << (*msg)(1) << endl;
}
};
int main()
{
A a;
a.run();
}
t.cpp: In member function 'void A::run()':
Line 19: error: no matching function for call to 'A::taunt()'
compilation terminated due to -Wfatal-errors.
I'm still getting the same error after changing (*msg)(int) to (B::*msg)(int)
b.getMsg is not the correct way to form a pointer to member, you need &B::getMsg.
(*msg)(1) is not the correct way to call a function through a pointer to member you need to specify an object to call the function on, e.g. (using a temporary) (B().*msg)(1).
The right way to do such things in OOP is to use interfaces so all you need to do is to define an interface and implement it in B class after that pass the pointer of instance which implements this interface to your method in class A.
class IB{
public:
virtual void doSomething()=0;
};
class B: public IB{
public:
virtual void doSomething(){...}
};
class A{
public:
void doSomethingWithB(IB* b){b->doSomething();}
};
This works in VS 2010. The output is the same on all lines:
#include <iostream>
#include <memory>
#include <functional>
using namespace std;
using namespace std::placeholders;
class A
{
public:
int foo(int a, float b)
{
return int(a*b);
}
};
int main(int argc, char* argv[])
{
A temp;
int x = 5;
float y = 3.5;
auto a = std::mem_fn(&A::foo);
cout << a(&temp, x, y) << endl;
auto b = std::bind(a, &temp, x, y);
cout << b() << endl;
auto c = std::bind(std::mem_fn(&A::foo), &temp, _1, y);
cout << c(5) << endl;
}
Basically, you use std::mem_fn to get your callable object for the member function, and then std::bind if you want to bind additional parameters, including the object pointer itself. I'm pretty sure there's a way to use std::ref to encapsulate a reference to the object too if you'd prefer that. I also included the _1 forwarding marker just for another way to specify some parameters in the bind, but not others. You could even specify everything BUT the class instance if you wanted the same parameters to everything but have it work on different objects. Up to you.
If you'd rather use boost::bind it recognizes member functions and you can just put it all on one line a bit to be a bit shorter: auto e = boost::bind(&A::foo, &temp, x, y) but obviously it's not much more to use completely std C++11 calls either.
#include <boost/bind.hpp>
#include <iostream>
using namespace std;
using boost::bind;
class A {
public:
void print(string &s) {
cout << s.c_str() << endl;
}
};
typedef void (*callback)();
class B {
public:
void set_callback(callback cb) {
m_cb = cb;
}
void do_callback() {
m_cb();
}
private:
callback m_cb;
};
void main() {
A a;
B b;
string s("message");
b.set_callback(bind(A::print, &a, s));
b.do_callback();
}
So what I'm trying to do is to have the print method of A stream "message" to cout when b's callback is activated. I'm getting an unexpected number of arguments error from msvc10. I'm sure this is super noob basic and I'm sorry in advance.
replace typedef void (*callback)(); with typedef boost::function<void()> callback;
A bound function doesn't produce an ordinary function, so you cannot just store it in a regular function pointer. However, boost::function is able to handle anything as long as it is callable with the correct signature, so that's what you want. It will work with a function pointer, or a functor created with bind.
After a few corrections to your code, I came up with this:
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <iostream>
// i prefer explicit namespaces, but that's a matter of preference
class A {
public:
// prefer const refs to regular refs unless you need to modify the argument!
void print(const std::string &s) {
// no need for .c_str() here, cout knows how to output a std::string just fine :-)
std::cout << s << std::endl;
}
};
// holds any arity 0 callable "thing" which returns void
typedef boost::function<void()> callback;
class B {
public:
void set_callback(callback cb) {
m_cb = cb;
}
void do_callback() {
m_cb();
}
private:
callback m_cb;
};
void regular_function() {
std::cout << "regular!" << std::endl;
}
// the return type for main is int, never anything else
// however, in c++, you may omit the "return 0;" from main (and only main)
// which will have the same effect as if you had a "return 0;" as the last line
// of main
int main() {
A a;
B b;
std::string s("message");
// you forget the "&" here before A::print!
b.set_callback(boost::bind(&A::print, &a, s));
b.do_callback();
// this will work for regular function pointers too, yay!
b.set_callback(regular_function);
b.do_callback();
}