I am trying to understand function pointers and I have the following test code:
#include <iostream>
using namespace std;
class Test {
public:
void test_func() {
cout << "Test func called.";
}
};
void outer_test_func(Test &t, void (Test::*func)()) {
(t.*func)();
}
int main(int argc, char *argv[]) {
auto t = Test();
outer_test_func(t, &Test::test_func);
}
This works. But from what I understand Test::test_func and &Test::test_func both result in pointers. So why can't I use the former instead of the latter? If I try it g++ complains.
But from what I understand Test::test_func and &Test::test_func both result in pointers.
Test::test_func is not a valid syntax for creating pointer to member function, nor pointer to data members. It has never been a valid C++ syntax.
From cppreference (emphasis mine),
A pointer to non-static member object m which is a member of class C can be initialized with the expression &C::m exactly. Expressions such as &(C::m) or &m inside C's member function do not form pointers to members.
Related
I'm learning the concept of passing a function as a parameter.
First I've tried pass a "free function?" (function that not belong to any class or struct) to another free function using this pointer void(*Func)(int) and it worked.
Second, a free function to a function belong to a struct using the same pointer, also worked.
But when I tried to pass a function in a struct to another function in a different struct with that same pointer, it prompted error.
Here's my code:
#include <iostream>
#include <stdio.h>
#include <windows.h>
#include <conio.h>
using namespace std;
struct A {
void Func_A (void (*Func)(int)) {
(*Func)(5);
}
};
struct B {
void Func_B (int a) {
cout<<a;
}
};
int main () {
A a;
B b;
a.Func_A(b.Func_B);
char key = getch();
return 0;
}
Here the error prompt:
[Error] no matching function for call to 'A::Func_A(<unresolved overloaded function type>)'
To pass a non-static member function around, the syntax is a little different. Here is your original code, reworked to show this:
#include <iostream>
struct B {
void Func_B (int a) {
std::cout << a;
}
};
struct A {
void Func_A (void (B::*Func)(int), B &b) {
(b.*Func) (5);
}
};
int main () {
A a;
B b;
a.Func_A (&B::Func_B, b);
return 0;
}
Note the different function signature for Func_A and the fact that you have to pass an instance of class B when you call it.
Live demo
It's a shame you can't use C++11. std::function makes this a lot simpler and more generalised.
Consider this example:
#include <iostream>
using namespace std;
struct A {
void Func_A (void (*Func)(int)) {
(*Func)(5);
}
};
struct B {
int x;
void Func_B (int a) {
cout << a << " " << x;
}
};
int main () {
A a;
B b1;
b1.x = 1;
B b2;
b2.x = 2;
a.Func_A(b1.Func_B);
return 0;
}
In that example, Func_B uses both the input a and the data member x, so it is clear that the result of a call to Func_B will be different depending on the object, if it is b1 or b2 that is calling it.
You might think that taking the function pointer "b1.Func_B" would clarify that you mean the function associated with the b1 object, but that does not work because the member functions do not exist separately for each instance. The function Func_B only exists once in memory, so it is not possible to have separate function pointers for "b1.Func_B" and "b2.Func_B". So, it cannot work.
The g++ 8.2.0 compiler gives the following error message for the a.Func_A(b1.Func_B); line in the code:
error: invalid use of non-static member function ‘void B::Func_B(int)’
hinting that it would be OK to do such a thing for a static member function. That makes sense, because a static member function cannot make use of the data members of any instance, so it is more like a "free function", not dependent on any instance.
I am using a framework that passes around function pointers as void*. I want a mock to return a function pointer, and I want to define the function in-place (like a lambda; which does not work as shown below).
A minimal working example is shown below.
#include <gtest/gtest.h>
#include <gmock/gmock.h>
using namespace std;
using namespace testing;
class Original
{
public:
typedef int(*fptr)();
void Func()
{
void* f = Func2();
fptr func = reinterpret_cast<fptr>(f);
if (func) {
int i = func();
if (i == 1) {
//do something
} else if (i == 3) {
//NOTE my unit test should test this decision branch
}
}
}
static int Func3() {return 1;}
virtual void* Func2() {return (void*)&Func3;}
};
class MyMock : public Original
{
public:
MOCK_METHOD0(Func2, void*());
};
My main goal: I want to get rid of this function, and define it inline in the EXPECT_CALL(). See below.
int MockFunc() {cout << "mock func" << endl; return 3;}
The test case:
TEST(MYTEST, Test)
{
MyMock m;
//WORKS: compiles and works as expected,
//but I do not want to use **MockFunc**
EXPECT_CALL(m, Func2()).Times(AtLeast(1))
.WillRepeatedly(Return(&MockFunc));
//DOES NOT WORK: Does not compile, of course
//(compiler message below this code block)
EXPECT_CALL(m, Func2()).Times(AtLeast(1))
.WillRepeatedly(Return((void*)&([](){return 3;})));
m.Func();
}
main.cpp:117:90: error: taking address of temporary [-fpermissive]
For completeness, the main():
int main(int argc, char** argv)
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
So the question again: How can I get rid of the MockFunc() function and define its contents in-place within the Return()?
The following statement should work:
EXPECT_CALL(m, Func2()).Times(AtLeast(1)).WillRepeatedly(Return((void*)(+([](){return 3;}))));
It exploits the fact that non-capturing lambdas decay to function pointers.
In other terms, the resulting type of the expression (+([](){return 3;}) is int(*)(). You can then cast it to void* as you did. The error should disappear as well, for you are no longer getting the address of a temporary.
So this is confusing to explain, but I will try my best.
I have a function one of my classes that takes a function pointer as an argument, and what I would like to do is define the function as part of the argument. ie:
object->setFunctionPointer({string a = ""; return a;});
Is this possible? if so, what is the proper syntax of this?
In C++11, you can do it. You can use C++ lambda (anonymous functions).
See the sample code at http://ideone.com/8ZTWSU
#include <iostream>
using namespace std;
typedef const char * (*funcptr)();
funcptr s;
void setFuncPtr(funcptr t)
{
s = t;
}
int main() {
// your code goes here
setFuncPtr([]{return "Hello \n"; });
printf("%s\n", s());
return 0;
}
If we are talking about C++ you should use std::function and not function pointers. Unless you are interfacing with C APIs.
class Foo{
SetFunc(std::function<void(int)> func)
{
m_func = func;
}
private:
std::function<void(int)> m_func;
};
If your function is a member of a class, you cannot take an ordinary function pointer to store its address. What you need is a delegate; which are specialised function pointers for methods. Search the internet for C++ delegate and you should find numerous examples.
(Note: maybe there is an exception for static methods; I don't remember.)
Here is a complete example. Since c++11 this is the way to go:
#include<functional>
#include<string>
#include<iostream>
using namespace std;
class Object
{
public:
void setFunctionPointer(function<string(void)> function)
{
m_function = function;
}
string run()
{
return m_function();
}
private:
function<string(void)> m_function;
};
int main(int argc, char**argv)
{
Object *object = new Object;
object->setFunctionPointer([]{string a = "FOO"; return a;}); // here is the function assignment
cout << object->run() << endl;
delete object;
}
When run this prints FOO to stdout.
I'm try to write a class member which calls another class member multiple times in parallel.
I wrote a simple example of the problem and can't even get to compile this. What am I doing wrong with calling std::async? I guess the problem would be with how I'm passing the the function.
#include <vector>
#include <future>
using namespace std;
class A
{
int a,b;
public:
A(int i=1, int j=2){ a=i; b=j;}
std::pair<int,int> do_rand_stf(int x,int y)
{
std::pair<int,int> ret(x+a,y+b);
return ret;
}
void run()
{
std::vector<std::future<std::pair<int,int>>> ran;
for(int i=0;i<2;i++)
{
for(int j=0;j<2;j++)
{
auto hand=async(launch::async,do_rand_stf,i,j);
ran.push_back(hand);
}
}
for(int i=0;i<ran.size();i++)
{
pair<int,int> ttt=ran[i].get();
cout << ttt.first << ttt.second << endl;
}
}
};
int main()
{
A a;
a.run();
}
compilation:
g++ -std=c++11 -pthread main.cpp
do_rand_stf is a non-static member function and thus cannot be called without a class instance (the implicit this parameter.) Luckily, std::async handles its parameters like std::bind, and bind in turn can use std::mem_fn to turn a member function pointer into a functor that takes an explicit this parameter, so all you need to do is to pass this to the std::async invocation and use valid member function pointer syntax when passing the do_rand_stf:
auto hand=async(launch::async,&A::do_rand_stf,this,i,j);
There are other problems in the code, though. First off, you use std::cout and std::endl without #includeing <iostream>. More seriously, std::future is not copyable, only movable, so you cannot push_back the named object hand without using std::move. Alternatively, just pass the async result to push_back directly:
ran.push_back(async(launch::async,&A::do_rand_stf,this,i,j));
You can pass the this pointer to a new thread:
async([this]()
{
Function(this);
});
Here is my code
#include <iostream>
using namespace std;
class MyTestClass
{
int MyTestIVar;
public:
MyTestClass(void);
int firstCallMethod(void);
int secondCallMethod(void);
};
MyTestClass::MyTestClass(void)
{
MyTestIVar = 4;
}
int MyTestClass::firstCallMethod(void)
{
return secondCallMethod();
}
int MyTestClass::secondCallMethod(void)
{
return MyTestIVar;
}
int main(int argc, char *argv[])
{
MyTestClass mTC;
cout << mTC.firstCallMethod() << endl;
return 0;
}
If use use
MyTestClass mTC();
instead it will disallow me to call any member functions and display this error
./experiment.cpp: In function ‘int main(int, char**)’:
./experiment.cpp:31:14: error: request for member ‘firstCallMethod’ in
‘mTC’, which is of non-class type ‘MyTestClass()’
I read the posts on value-initialize etc, but this error still doesn't seem logical to me. Why would this affect member functions?
And help greatly appreciated :-)
MyTestClass mTC();
Does not declare an object of the MyTestClass class, as you think.
It Actually, declares a function by the name of mTC which does not take any parameters and returns an MyTestClass object.
This is known as the Most Vexing Parse in c++.
You have stumbled upon the most vexing parse.
The line
MyTestClass mTC();
is parsed as a function prototype of a function named mTC which has no arguments and returns an instance of MyTestClass.