C++ access callback data - c++

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);

Related

Is there any way to "capture" local scope template variables (akin to a lisp special) and use as default?

In the following code:
#include <iostream>
#include <type_traits>
// this code below won't compile unless at this point there is already
// a typename rate
// using rate = std::integral_constant<int, 10>;
template<typename rate=rate> void functionA()
{
static_assert(rate::value > 5);
std::cout << "functionA: " << rate::value << std::endl;
}
template<typename rate> void loop()
{
functionA<std::integral_constant<int, 50>>(); // => prints "functionA: 50"
functionA(); // <- I would like this call to infer loop's functions's rate template type (which would be 20)
}
void other()
{
using rate = std::integral_constant<int, 12>;
functionA(); // => prints "functionA: 12"
}
void bare_loop()
{
functionA(); // should give compile time-error: no 'rate' in semantic scope
}
int main() {
loop<std::integral_constant<int, 20>>();
return 0;
}
I would like to be able to write a templated function which has a default parameter value which remains undeclared until compilation is necessary.
The above shows the most minimal piece of code to express this idea.
What I'm trying to achieve is directly inspired by Lisp's variable capture mechanism (lexical and dynamic scope).
To be clear: this is entirely a compile-time problem and solution.
Is this possible in the current state of affaires of C++?
I am really not sure if I understood what you intended, but if you want is a function that could either take the parameter rate at compile time or at runtime, well, one possibility would be to use a default parameter in function "functionA", determined by the template parameter. So you can define the default in compile time, and override it in runtime if needed.
I leave an example below in case it helps, however I can't understand what it the desired use case, and it can be possibly
a bad design:
#include <iostream>
#include <cassert>
constexpr int infer() { return 123; }
const int MIN_RATE_LIM = 5;
template<int t_rate=infer()> void functionA(const int rate = t_rate)
{
assert(rate > MIN_RATE_LIM);
std::cout << "functionA: " << rate << std::endl;
}
template<int rate> void loop()
{
for(int i = 0; i < 10; i++ )
{
functionA<50>();
functionA<rate>();
functionA<rate>(12); // <- 12 will overlap the value 10 in this line
}
}
int main() {
loop<10>();
return 0;
}

Pointers to undefined functions and parameters in C ++

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;
}

Is it possible to call a method from an instance that doesn't exist?

The code I'm working on :
I had the following code (with an error about the index in main.cpp) :
Sample.hpp :
#ifndef SAMPLE_HPP
# define SAMPLE_HPP
# include <iostream>
# include <string>
class Sample{
public:
Sample(void);
~Sample(void);
void tellname(void) const;
private:
std::string _name;
};
#endif
Sample.cpp :
#include <iostream>
#include "Sample.hpp"
Sample::Sample(void){
this->_name = "testname";
return;
};
Sample::~Sample(void){
return;
}
void Sample::tellname(void) const{
std::cout << "Name : " << this->_name << std::endl;
return;
}
main.cpp
#include "Sample.hpp"
int main(void){
int i;
Sample *test;
test = new Sample[4];
i = 0;
while (i++ < 4) // I know : i++; shouldn't be here
test[i].tellname();
delete [] test;
return 0;
}
If I compile this I get the following output :
Name : testname
Name : testname
Name : testname
Name :
My question is :
About the last line, it calls a method (void Sample::tellname(void)) but from an instance that is not in the range of the table (test[4] doesn't exist).
However, it still calls tellname() even the instance it calls it from doesn't exist. It just considers its _name field being empty.
How is this possible?
It's simply undefined behavior, something C++ imposes no requirements on so "anything could happen". What you're seeing is just a coincidence and worthless to reason about: next time you run it could crash, display nyan cat and so on.
It sounds like you are wondering why the function is called. In memory, structs do not contain the functions inside them. Instead, one copy of the functions are placed somewhere in the executable. So when you are calling test[4].tellname() what is really happening is: The address test + (4 * sizeof(Sample)) is passed to the function tellname(). The value at that address is undefined.
Here is an example to give you an idea of what is going on:
#include <iostream>
struct astruct {
int i = 0;
void prnt()
{
std::cout << i << '\n';
}
};
struct bstruct {
int y = 100;
};
int main()
{
bstruct b;
((astruct*)&b)->prnt();
getchar();
return 0;
}
Here prnt() is behind the scenes being passed the address of bstruct and treats it like the address of an astruct, since the first value in bstruct is 100, it prints 100. You can even simplify it to this:
#include <iostream>
struct astruct {
int i = 0;
void prnt()
{
std::cout << i << '\n';
}
};
int y = 100;
int main()
{
((astruct*)&y)->prnt();
getchar();
return 0;
}
i goes from 1 to 4 include, since tellname is const, test[4].tellname() is Sample::tellname with Sample being an undefined structure so "Name :" is rightfully printed then the memory in test[4]._name is printed and luckily the memory pointed by test[4]._name* is non null and is even a end string char.
So yeah you are lucky.

C++ Initialization of static function pointer array

I want to create a static function pointer array, so I can jump to a certain function regarding a received index. Like an index jumper.
So imagine a class like this:
Class A
{
private:
static void 1stFunction();
static void 2ndFunction();
static void(*functionPointer[20])(void);
};
Then I would like that functionPointer to get the value of the 1stFunction and 2ndFunction, and maybe even more.
So, how do I initialize it?
As far as I know, when a static member is declared, you can use it even before an instance is created. So I though, lets initialize that function pointer, so later I can call it like this
functionPointer[receivedIndex]();
So i tried to initilize it like this, in the same .h file
void (*A::functionPointer[])(void) =
{
A::1stFunction,
A::2ndFunction,
};
But the compiler gives me redifinition, it says it's already created.
So, pretty sure I'm missing something. I don't know though, if it is syntax or simply it is not possible to do it this way.
I know that function pointers to class's member functions are different than normal function pointers... But this is a static function, so I believe it doesn't belong to an instance and therefore it should work with normal function pointers.
Any help would be appreciated.
Thanks
The following would be a working example that probably achieves what you need.
You need C++11 for the initializer list.
It is a good practice to initialize the static member in the cpp file, as you don't want to have a definition of the static member everytime the header is included (this can lead to linking issues).
You can call callf with the desired index and have the corresponding function called, based on the initialization of the function pointer array.
The output of the program would be:
I am 2ndFunction
Header file
class A
{
private:
static void Function1();
static void Function2();
static void(*functionPointer[20])();
public:
static void callf(int index);
};
Implementation
#include <iostream>
#include "ex.h"
void(*A::functionPointer[20])() {
A::Function1,
A::Function2
};
void A::Function1() {
std::cout << "I am 1stFunction" << std::endl;
}
void A::Function2() {
std::cout << "I am 2ndFunction" << std::endl;
}
void A::callf(int index) {
A::functionPointer[index]();
}
int main(int argc, char const *argv[]) {
A::callf(1);
return 0;
}
Here you have a more modern C++ approach (C++14 needed)
I would advise you to explore lambda functions if you are not restricted to C++03.
#include <iostream>
#include <functional>
#include <vector>
class A {
public:
using f_type = std::function<void(void)>;
f_type f1 = []() { std::cout << "f0" << std::endl;};
f_type f2 = []() { std::cout << "f1" << std::endl;};
static void f3() { std::cout << "f3" << std::endl; }
std::vector<f_type> functions{f1, f2, f3};
};
int main() {
A a;
a.functions[0]();
a.functions[1]();
//adding custom lambda
a.functions.emplace_back([](){ std::cout << "custom f" << std::endl;});
a.functions[2]();
return 0;
}
you can add both functions and lambdas to your container.

C++ Function Pointer as Argument

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();
}