Difficulty in passing function pointer of a class member function - c++

In trying to implement a suggested answer here in my own context, I am running into a compilation error.
Consider code:
#include <iostream>
class SIMPLE {
public:
SIMPLE() { for (int i = 0; i < 5; i++) val[i] = 5; };
int retval(int index) { return val[index]; }
private:
int val[5];
};
void print_array_of_length5(int (*fnptr)(int index)){
for (int i = 0; i < 5; i++)
printf("%d ", fnptr(i));
}
int global_array[5] = { 0, 1, 2, 3, 4 };
int global_function(int index){
return global_array[index];
}
int main(){
print_array_of_length5(&global_function);//Works fine.
int (SIMPLE::*p)(int) = &SIMPLE::retval;//Following method suggested in the answer above
class SIMPLE smpl;
print_array_of_length5(smpl.*p);//Compile error: a pointer to a bound function may only be used to call the function
}
The function works when supplied with the address of a global function. It does not work when passed smpl.*p analogous to the method suggested. How should one fix this error?

You need another overload for print_array_of_length5 in order to pass a member function pointer:
template<typename T>
void print_array_of_length5(int (T::*fnptr)(int index), T& obj)
{
for(int i = 0; i < 5; ++i)
{
printf("%d ", (obj.*fnptr)(i));
}
}
int main()
{
SIMPLE smpl;
print_array_of_length5(&SIMPLE::retval, smpl);
}

You can't pass a non-static member function pointer as a regular function pointer. Member functions have access to the this pointer, and the way they get that is via an invisible implicit function parameter. You need to have the object on which to call the function, and the function itself, be bound together, which a function pointer simply can't do.
What we can do is make print_array_of_length5 a function template, and allow it to take any type of callable. That would give you something like this:
template <typename Function>
void print_array_of_length5(Function func){
for (int i = 0; i < 5; i++)
printf("%d ", func(i));
}
To call it with a non-static member function, you can use a lambda expression, or std::bind(), like this:
SIMPLE smpl;
print_array_of_length5([&smpl](int foo){ return smpl.retval(foo); });
using namespace std::placeholders;
SIMPLE smpl;
auto func = std::bind(&SIMPLE::retval, &smpl, _1);
print_array_of_length5(func);

Related

How to pass object array to a function?

class department
{
void max() ***HOW TO PASS ARRAY OF OBJECT HERE , WHAT PARAMETERS SHOULD I PASS***
{
}
};
class B : public department {
};
int main()
{
B a[10];
// a.max(a,n); ***HOW TO CALL THIS max FUNCTION***
return 0;
}
I want to pass the array of object a[10] to the max function. How do I call it and pass it?
I don't want to do it like this:
for(i = 0; i < n; i++)
{
a[i].max
}
You implemented max() as a non-static method of department, so you need a department object to call it on, like each B object in your array, eg:
for(int i = 0; i < 10; ++i)
{
a[i].max();
}
If this is not what you want, then max() needs to be taken out of department, or at least made to be static instead. Either way, you will have to change its input parameters to accept the array.
Try something more like this instead:
class department
{
public:
static void max(department *depts, int count)
{
//...
}
};
class B : public department {
};
int main()
{
B a[10];
department::max(a, 10);
return 0;
}
Online Demo
Alternatively:
class department {
};
class B : public department {
};
void max(department *depts, int count)
{
//...
}
int main()
{
B a[10];
max(a, 10);
return 0;
}
Online Demo
How to pass object array to a function?
The parameter of a function cannot be an array in C++. A parameter can be a reference to an array. Alternatively, it is common to pass iterator pointing to an element of an array. Object pointer is an iterator for an array.
department::max() is a non-static member function. It has empty parameter list, so it accepts no arguments at all, except for the implicit class instance that is used as the left hand operand of a member access operator. Since this function accepts no reference to array parameter nor a pointer parameter, there's no way to pass an array as an argument.
Here is an example of a function that does accept a reference to an array as a parameter, and of how to call such function:
void max(B (&arr)[10]);
int main()
{
B a[10];
max(a);
}

How can I use template class as parameters of function?

I want threading with template class parameter, but I don't know how I can use template class as parameter of thread method.
I already tried making method in template class, but I don't want it. People generally do not use this solution.
//....
//Linked List code
//.....
void func1(slist<T> s){
for (int i = 0; i < 1000; i++) {
s.push_(i);
}
} // this part is problem of my code.
int main() {
int i;
slist<int> s;
thread t1(func1,s); //Compile error.
func1(s); // here, too.
return 0;
}
i expect the result that threads compete with Linked list.
The generic solution:
template<typename T>
void func1(slist<T>& s){
for (int i = 0; i < 1000; i++) {
s.push_(i);
}
}
Or you can specialise for one specific type:
void func1(slist<int>& s){
for (int i = 0; i < 1000; i++) {
s.push_(i);
}
}
(Also be aware that you probably want to pass a reference to the list, rather than a copy)
As you want to make the thread accept a template, the function should be templated too.
template <typename T>
void func1(slist<T> s){ // most likely you need to pass by reference
for (int i = 0; i < 1000; i++) {
s.push_(i);
}
}
While calling the function in main,
int main() {
int i;
slist<int> s;
thread t1(func1<int>,s); //t1 needs to know which type it needs to instantiate of func1
t1.join(); // let the thread finish
return 0;
}

Invoke a function in context of a class instance or method for performance analysis

Performance analysis question: Is there a way to execute a function in context of a class, or a method of a class?
I would like to analyze the performance of a specific segment of logic. What I envision is something like this
(Disclaimer: rough example just to illustrate a point. Will not compile).
const int DEBUG_LEVEL = 7;
class PerfWrapper {
public:
PerfWrapper(int f) {} // Constructor: take function as argument
void invoke() {} // Invoke the function passed as argument
double execution_time() {
begin = std::chrono::high_resolution_clock::now();
// etc..
}
double memory_usage() {}
private:
}
int foo() {
int sum{0}
for (int i=0; i<1000; ++i)
for (int j=0; j<MAX; ++j)
sum += i * j;
return sum;
}
int main() {
if (DEBUG_LEVEL = 7)
PerfWrapper p(foo); // Create an instance, passing foo as an argument
// below foo() is called in context of the performance wrapper
int myTime = p.invoke().execution_time(); // Invokes foo in context of p and tracks execution time
int myMemory = p.invoke().memory_usage(); // Same, except gathering memory usage info.
// etc..
}
}
Here we have class PerfWrapper. When instantiated, resulting methods on the object have the ability to accept a function as an argument, and execute a function in context of the class. It will take perf measurements, results of which are accessible through the interface.
Note the "DEBUG_LEVEL" setting. If performance profiling is needed then simply set the DEBUG_LEVEL to 7.
Have you seen anything like this? If not, how is the analysis best accomplished? I know that it seems a bit out there, but hopefully not so much. Thx, Keith :^)
Maybe you are looking for function pointers, which could be used as shown in the following simplified code:
typedef int(*aFooFunctionType)(void);
class PerformanceTest {
public:
PerformanceTest(aFooFunctionType fooFuncPtr) { m_fooFuncPtr = fooFuncPtr; }
void test() {
int x = m_fooFuncPtr();
// do something with x (or not...)
};
private:
aFooFunctionType m_fooFuncPtr;
};
int fooFunc(void) {
return 100;
}
int main(int argc, char* argv[]) {
PerformanceTest pTest(fooFunc);
pTest.test();
return 0;
}
You can wrap almost anything in a std::function. I would suggest use of a std::function in PerfWrapper to get the execution time. I don't have anything for measuring memory usage, though.
Example code:
#include <iostream>
#include <functional>
#include <chrono>
class PerfWrapper
{
public:
PerfWrapper(std::function<void()> f) : f_(f), execution_time_{} {}
void invoke()
{
auto begin = std::chrono::high_resolution_clock::now();
f_();
auto end = std::chrono::high_resolution_clock::now();
execution_time_ = end-begin;
}
double execution_time()
{
return execution_time_.count();
}
std::function<void()> f_;
std::chrono::duration<double> execution_time_;
};
unsigned long foo()
{
unsigned long sum{0};
for (int i=0; i<10000; ++i)
for (int j=0; j<2000; ++j)
sum += i * j;
return sum;
}
int main()
{
PerfWrapper pr([](){std::cout << foo() << std::endl;});
pr.invoke();
std::cout << "Execution time: " << pr.execution_time() << std::endl;
}
Output on my setup:
99940005000000
Execution time: 0.0454077
Consider using a template free function, with a reference parameter to extract the performance data. This example will:
Accept function pointers and functors (including std::function, which means it can work with methods, too).
Return the same value the proxied function call returns, so you can use both the measurement data and the call result.
struct measurement {
double execution_time;
double memory_usage;
};
template <typename FN, typename... T>
inline auto measure(FN fn, measurement& m, T&&... args) -> decltype(fn(std::forward<T>(args)...))
{
auto&& result = fn(std::forward<T>(args)...);
m.execution_time = 0; // example
m.memory_usage = 0;
return result;
}

Organising C++ code

I am looking for some advice on how to organise my C++ code.
I have an int array, side, that I would like to be static in the sense that its value is kept constant between calls. This is because my function foo(), will modify the array side recursively and so I don't want copies to be made of side. Furthermore, the size of side can only be determined at compile time from the size of a vector that is passed into the function bar().
I have thought of the following structure to layout such a problem.
I keep a global int pointer, side, which I can then use to point to the address of my int array and then use the pointer *side within foo to do my modifications.
Please can you give me advise on the layout and organisation of this code? I am quite new to C++ so would appreciate any advice on the below structure.
#include <iostream>
#include <vector>
using namespace std;
int *side;
class A {
public:
int foo(bool);
int bar(vector<int>);
void set_n(int n){ class_n = n;};
private:
int class_n;
};
int A::foo(bool fl)
{
int n = class_n;
for(int i = 0; i < n; i++) {
// modify side[] and then recursively call foo
}
return 0;
}
int A::bar(vector<int> t)
{
int size = t.size();
set_n(size);
int a = foo(true);
int *side_local = new int[size];
for(int i = 0; i < size; i++) {
side_local[i] = 0;
}
side = side_local;
return 0;
}
int main()
{
A a;
vector<int> t = {1, 2, 3};
a.bar(t);
return 0;
}
A recursive call can pass a pointer to itself:
void foo(int *pList)
{
foo(pList); // recursive
}
the same list is then being worked on.
That being said, since foo is inside a class you wouldn't need a global either, but a member variable.
class A
{
int *pMemberList;
...
void foo();
}
now foo can see pMemberList all the time.
BUT ... passing it is probably a better option as in the future your class might house 2 lists that you want to do foo on.

Passing reference of vector of objects as arguments in C++

I'm trying to build a function in which an argument is a reference to a vector of objects. In this case name of the object is 'obj', it is an instance of the class 'Example' and it is a vector as defined in vector class. Object have members like x, y and z.
The reason I'm trying with passing references is because I want to change the value of obj.z by making use of obj.x and obj.y from inside of the function.
#include <vector>
#include <iostream>
using namespace std;
class Example{
public:
double x;
double y;
double z;
Example()
: x(0.0),y(0.0){
}
};
void calculate(Example &obj, int M) {
for(int i = 0; i < M; i++) {
obj[i].z = obj[i].x * obj[i].y;
}
}
int main() {
vector<Example> obj;
int N = 10;
calculate(obj, N);
}
When I run this, I get the following errors:
Inside of the function I have: "Type 'Example' does not provide a subscript operator."
I google'd it and saw that it is related to operator overloading and usage of references. The solution is probably related to dereferencing my object reference inside of the function, but I wasn't able to manage this one right currently.
And the second error is outside of the function, inside the main() at the line where I call the function: "No matching function for call to 'calculate'".
Here, I assume the error is related to the fact that obj is not just an object but a vector of objects, so I should change the argument somehow. But I haven't been able to correct this one up to now as well.
So, to summarize, I want to pass a vector of objects to a function as reference, because I want to be able to change a member of the object inside of the function.
Thank you in advance.
I want to pass a vector of objects to a function as reference
So do that:
void calculate(vector<Example> &obj) {
for(int i = 0; i < obj.size(); i++) {
obj[i].z = obj[i].x * obj[i].y;
}
}
int main() {
vector<Example> obj;
// put some values into it...
calculate(obj);
}
I believe you wanted your function to be
void calculate(vector<Example> &obj, int M)
and not
void calculate(Example &obj, int M)
obj[i]
'obj' isn't an array.
You need to declare it as:
void calculate(Example* obj, int M)
And rather
void calculate(vector<Example>& v)