Error in vector of struct with implemented Functions - c++

I get the Erro:
"no instance of constructor "std::vector<_Ty, _Alloc>::vector
[with _Ty=FunctionToUpdate, _Alloc=std::allocator<FunctionToUpdate>]" matches the argument list"
No matter how I change it, it persists, as long I keep it as a class. If I keep it all in just a simple .cpp without class and header, it all resolves easily.
My.h:
#include <vector>
#include <functional>
#include <iostream>
struct Params
{
std::vector<int> Integers;
std::vector<std::string> Strings;
};
struct FunctionToUpdate
{
int Version;
std::function<void(int, Params)> Function;
Params Parameters;
};
class Error
{
public:
Error();
void testFunctionA(int a, Params p);
void testFunctionB(int a, Params p);
protected:
const static std::vector<FunctionToUpdate> table;
};
Here is my .cpp, please assist me, I can't find the error:
#include "ErrorHandling.h"
Error::Error()
{
for (auto functionToUpdate : table)
{
functionToUpdate.Function(functionToUpdate.Version, functionToUpdate.Parameters);
std::cout << "############################################" << std::endl;
}
std::cout << "Done!" << std::endl;
}
void Error::testFunctionA(int a, Params parameter)
{
//std::cout << "Size Integers: " << parameter.Integers.size() << std::endl;
//std::cout << "Size Strings: " << parameter.Strings.size() << std::endl;
std::cout << a << std::endl;
for (auto& integer : parameter.Integers)
{
std::cout << integer << std::endl;
}
for (auto& integer : parameter.Strings)
{
std::cout << integer << std::endl;
}
}
void Error::testFunctionB(int a, Params parameter)
{
std::cout << a << std::endl;
std::cout << parameter.Integers.at(0) << std::endl;
}
const std::vector<FunctionToUpdate> Error::table
{ // <-- here the Error happens
{ 100, &testFunctionA, { {177}}},
{ 1948, &testFunctionB, { {314}}},
};
int main()
{
Error error;
}

Your code has a few issues
First, the correct initialization of static member Error::table would be as follows:
const std::vector<FunctionToUpdate> Error::table
{
{ 100, &Error::testFunctionA, { { {177} }, { {"string"} } }},
{ 1948, &Error::testFunctionB, { { {314} }, { {"string"} } } }
};
Note that the syntax &Error::testFunctionA for addressing the member function pointer. Additionally, the Params has two vectors. One is std::vector<int> and the other is std::vector<std::string>. In your code, the std::vector<std::string> has not been mentioned.
In FunctionToUpdate the member function pointer type is wrong. Using typed member function pointer, you could
// forward declaration
class Error;
// member function pointer type
using ErrorFunType = void(Error::*)(int, Params);
struct FunctionToUpdate
{
int Version;
ErrorFunType Function;
Params Parameters;
};
Secondly, the call to pointer to the member function in Error::Error() is wrong. It needs an (Error class) instance to call with. For example:
for (auto functionToUpdate : table)
{
(this->*functionToUpdate.Function)(
functionToUpdate.Version, functionToUpdate.Parameters
);
// or more generic `std::invoke` (since c++17)
// std::invoke(functionToUpdate.Function
// , this, functionToUpdate.Version
// , functionToUpdate.Parameters);
// ...
}
The above changes will make, your code compiles again!
In case of wondering, how to handle the pointer to member function with std::function, (one way) to wrap the instance to call the member along with the std::function type.
Following is the example:
// forward declaration
class Error;
// member function pointer
using ErrorFunType = std::function<void(Error*, int, Params)>;
struct FunctionToUpdate
{
int Version;
ErrorFunType Function;
Params Parameters;
};
now in Error::Error()
Error::Error()
{
for (auto functionToUpdate : table)
{
functionToUpdate.Function(this
, functionToUpdate.Version, functionToUpdate.Parameters);
}
}
See a demo

Related

How can I access the `typeid` of a captured this pointer in a lambda?

I have the following code:
#include <iostream>
class Bobo
{public:
int member;
void function()
{
auto lambda = [this]() { std::cout << member << '\n'; };
auto lambda2 = [this]() { std::cout << typeid(*this).name() << '\n'; };
lambda();
lambda2();
}
};
int main()
{
Bobo bobo;
bobo.function();
}
The line std::cout << typeid(*this).name(); in lambda2() understandably prints out:
class <lambda_49422032c40f80b55ca1d0ebc98f567f>
However how can I access the 'this' pointer that's been captured so the typeid operator can return type class Bobo?
Edit: The result I get is from compiling this code in Visual Studio Community 2019.
This seems to be VS's bug; when determining the type of this pointer in lambda:
For the purpose of name lookup, determining the type and value of the
this pointer and for accessing non-static class members, the body of
the closure type's function call operator is considered in the context
of the lambda-expression.
struct X {
int x, y;
int operator()(int);
void f()
{
// the context of the following lambda is the member function X::f
[=]()->int
{
return operator()(this->x + y); // X::operator()(this->x + (*this).y)
// this has type X*
};
}
};
So the type of this should be Bobo* in the lambda.
As #songyuanyao suggests, your could should work and produce the appropriate typeid, so it's probably a bug. But - here's a workaround for you:
#include <iostream>
class Bobo
{public:
int member;
void function() {
auto lambda = [this]() { std::cout << member << '\n'; };
auto lambda2 = [my_bobo = this]() {
std::cout << typeid(std::decay_t<decltype(*my_bobo)>).name() << '\n';
};
lambda();
lambda2();
}
};
int main() {
Bobo bobo;
bobo.function();
}
Note that you can replaced typeid(...).name() with the proper type name, obtained (at compile-time!) as per this answer:
std::cout << type_name<std::decay_t<decltype(*my_bobo)>>() << '\n';

How to call a C++ class method, which is given as a parameter?

I'm trying to pass a method as a parameter to other method.
Magner.h:
Class Manager{
public:
timeCount(void (Manger::*function)(void));
void passedFuction();
}
In Manager.cpp, I'm trying to call timeCount by
timeCount(&Manager::passedFuction());
TimeCount Body:
void Manager::timeCount(void(Manager::*function)(void))
{
std::cout << "It works";
(*function)(); // here is error
}
ViusalStudio says:
void*Manager::*function)() operand of '*' must be a pointer
How should i correct it?
The example i was learing by was : http://www.cplusplus.com/forum/beginner/6596/
A pointer-to-member-function (pmf) is not a pointer. Let me repeat that:
A pointer-to-member-function is not a pointer.
To call a pmf, you have to provide it with the object you want to call it on. You probably want:
(this->*function)();
If you had another object obj of the right type, you could also use:
(obj.*function)();
The void (Manger::*function)(void) syntax is for member functions of Manager class, which cannot be used with functions outside the Manager class.
To fix this shortcoming, pass std::function<void(void)> instead, which would let you invoke itself using the regular function invocation syntax:
void Manager::timeCount(std::function<void(void)> f) {
std::cout << "It works";
f();
}
Here is a complete demo of how to call timeCount with member and non-member functions:
struct Manager {
string name;
void timeCount(std::function<void(void)> f) {
std::cout << "This is " << name << " manager" << endl;
f();
}
};
void foo() {
cout << "I'm foo" << endl;
}
struct Test {
int x;
void bar() {
cout << "I'm bar " << x << endl;
}
};
int main() {
Manager mgr {"time"};
mgr.timeCount(foo);
Test tst = {234};
mgr.timeCount(std::bind( &Test::bar, tst));
return 0;
}
Demo.
Since c++17, we have std::invoke:
std::invoke(function, this);
or
std::invoke(function, *this);
are both ok. Minimal demo:
#include <functional>
#include <iostream>
class Manager
{
public:
void timeCount(void (Manager::*function)(void));
void passedFuction()
{
std::cout << "call passedFunction\n";
}
};
void Manager::timeCount(void (Manager::*function)(void))
{
std::cout << "It works\n";
std::invoke(function, *this);
// (*function)(); // here is error
}
int main()
{
Manager a;
a.timeCount(&Manager::passedFuction);
}
It works
call passedFunction
live demo

C++: How to store various member functions of different classes for later use

thanks in advance for your support.
I'm using C++11 and I want to store public member functions of some classes for later use as callback functions; e.g. I want to store some functions that matches this template: void(classname::*)(void). As far as I know, I have to store their objects too, It's fine. For example:
// PSEUDO CODE
class A {
public:
void myfunc() {}
}myobj;
class B {
public:
void myfunc2() {}
}myobj2;
/* storing */
mystorageclass storage;
storage.push(&myobj, &A::myfunc);
storage.push(&myobj2, &B::myfunc2);
/* call them back */
(storage[0].object->*(storage[0].callback))();
(storage[1].object->*(storage[1].callback))();
Is there any safe and generic way to do that? Actually I've found a way, but I'm not sure how much it's portable across processors or compilers.
//test.cpp - compiled with: g++ test.cpp -o test -std=c++11
#include <iostream>
#include <vector>
class A {
public:
void myfunc() { std::cout << "Test A::myfunc()" << std::endl; }
}myobj;
class B {
public:
void myfunc2() { std::cout << "Test B::myfunc2()" << std::endl; }
}myobj2;
struct Callback {
void* object;
void(* method)(void*);
};
std::vector<Callback> callbackList;
template<typename FunctionPtr>
void add(void* object, FunctionPtr fptr) {
Callback cb;
cb.object = object;
cb.method = (void(*)(void*))(*(void**)(&fptr));
callbackList.push_back(cb);
}
int main() {
//add to list for later use
add(&myobj, &A::myfunc);
add(&myobj2, &B::myfunc2);
//call them back
callbackList[0].method(callbackList[0].object);
callbackList[1].method(callbackList[1].object);
}
And another way to do; I feel this is much more safe:
//test2.cpp - compiled with: g++ test2.cpp -o test2 -std=c++11
#include <iostream>
#include <vector>
class A {
public:
void myfunc() { std::cout << "Test A::myfunc()" << std::endl; }
}myobj;
class B {
public:
void myfunc2() { std::cout << "Test B::myfunc2()" << std::endl; }
}myobj2;
struct Callback {
struct A;
A* object;
void(A::* method)();
void call() {
(object->*method)();
}
};
std::vector<Callback> callbackList;
template<typename FunctionPtr>
void add(void* object, FunctionPtr fptr) {
Callback cb;
cb.object = (Callback::A*)object;
cb.method = (void(Callback::A::*)())(fptr);
callbackList.push_back(cb);
}
int main() {
//add to list for later use
add(&myobj, &A::myfunc);
add(&myobj2, &B::myfunc2);
//call them back
callbackList[0].call();
callbackList[1].call();
}
Does these usages are safe? Or what do you suggest instead of these.
Thanks.
Replace Callback with std::function<void()>.
Replace add with
template<class T, class R, class U>
void add(T* object, R(U::*ptr)()) {
Callback cb = [object, ptr]{ object->ptr(); };
callbackList.push_back(cb);
// or just
// callbackList.push_back([object, ptr]{ object->ptr(); });
}
note that this supports passing in pointers-to-parent member functions, and callbacks that do not return void and discarding the result.
std::function stores a generic "call this later". You pass a type compatible with the return value, and args compatible with what you want to call later, in the template signature argument of std::function<signature>. In this case, <void()>.
Problem with the second version
In the line
cb.method = (void(*)(void*))(*(void**)(&fptr));
you are casting a function pointer to void**. I am not sure that is supported by the standard. My guess is it is not. I know casting a function pointer to void* is not supported by the standard. See Print an address of function in C++, g++/clang++ vs vc++ , who is rght? for details.
And then, you proceed to use:
callbackList[1].method(callbackList[1].object);
This relies on conventions used by a compiler to pass this as the first hidden argument when calling a member function of a class. There is no guarantee that the method is used by all compilers. The standard does not explicitly state that.
Problem with the third/last version
You are using:
cb.object = (Callback::A*)object;
cb.method = (void(Callback::A::*)())(fptr);
regardless of whether the object type is A or B. This is cause for undefined behavior. The standard does not support casting of an object pointer to any old pointer type.
A Cleaner Version
Use a base class for Callback.
struct Callback {
virtual ~Callback() = 0;
virtual void call() = 0;
};
Then, use a class template for the real Callbacks.
template <typename T>
struct RealCallback : public Callback
{
RealCallback(T* obj, void (T::*m)(void)) : object(obj), method(m) {}
virtual void call()
{
(object->*method)();
}
T* object;
void (T::*method)();
};
With this, you won't be able to store a list of Callback objects but you can store a list of shared_ptr<Callback>s.
std::vector<std::shared_ptr<Callback>> callbackList;
Here's a complete program that does not rely on any ugly casts and works perfectly.
//test.cpp - compiled with: g++ test.cpp -o test -std=c++11
#include <iostream>
#include <vector>
#include <memory>
class A {
public:
void myfunc() { std::cout << "Test A::myfunc() on " << this << std::endl; }
}myobj;
class B {
public:
void myfunc2() { std::cout << "Test B::myfunc2() on " << this << std::endl; }
}myobj2;
struct Callback {
virtual void call() = 0;
};
template <typename T>
struct RealCallback : public Callback
{
RealCallback(T* obj, void (T::*m)(void)) : object(obj), method(m) {}
virtual void call()
{
(object->*method)();
}
T* object;
void (T::*method)();
};
std::vector<std::shared_ptr<Callback>> callbackList;
template<typename T>
void add(T* object, void (T::*fptr)()) {
RealCallback<T>* cb = new RealCallback<T>(object, fptr);
callbackList.push_back(std::shared_ptr<Callback>(cb));
}
int main() {
//add to list for later use
add(&myobj, &A::myfunc);
add(&myobj2, &B::myfunc2);
std::cout << "myobj: " << &myobj << std::endl;
std::cout << "myobj2: " << &myobj2 << std::endl;
//call them back
callbackList[0]->call();
callbackList[1]->call();
}
Update, in response to comment by Yakk
I think Yakk's suggestion makes sense. You can remove the classes Callback and RealCallback with
using Callback = std::function<void()>;
std::vector<Callback> callbackList;
Then, add can be simplified to:
template<class T>
void add(T* object, void(T::*ptr)()) {
callbackList.push_back([object, ptr]{ (object->*ptr)();});
}
With those changes, main needs to be slightly updated to:
int main() {
//add to list for later use
add(&myobj, &A::myfunc);
add(&myobj2, &B::myfunc2);
std::cout << "myobj: " << &myobj << std::endl;
std::cout << "myobj2: " << &myobj2 << std::endl;
// Updated. Can't use callbackList[0]->call();
//call them back
callbackList[0]();
callbackList[1]();
}
Try with std::function or std::bindboth of them need to keep the reference to the instance:
#include <string>
#include <iostream>
#include <functional>
using namespace std;
class MyClass
{
int _value;
public:
MyClass(int value)
{
_value = value;
}
void food()
{
cout << "Foo is doing something whit value: " << _value << endl;
}
void bar()
{
cout << "Bar is doing something whit value: " << _value << endl;
}
};
int main()
{
MyClass* c1 = new MyClass(1);
MyClass* c2 = new MyClass(2);
cout << "Using 'std::function':" << endl;
std::function<void(MyClass&)> food = &MyClass::food;
std::function<void(MyClass&)> bar = &MyClass::bar;
food(*c1);
bar(*c1);
food(*c2);
bar(*c2);
cout << "Using 'std::bind':" << endl;
auto foodBind = std::bind(&MyClass::food, std::placeholders::_1);
auto barBind = std::bind(&MyClass::bar, std::placeholders::_1);
foodBind(*c1);
barBind(*c1);
foodBind(*c2);
barBind(*c2);
system("PAUSE");
};
the Output is:

how pass an array as parameter, and the array is defined in the parameters in c++

I am converting a c# written program into c++ code. I have a c# function declaration like:
// c# function declaration
int DerivationFunc(int id, params BasicFeature[] args);
So I convert it to c++
// c++ function declaration
int DerivationFunc(int id, BasicFeature* args, int argsNum); // argsNum denotes the size of the array
Now I have problems when calling the functions. In c#, I can call the function with the array definition in the parameters:
// c# function calling
DerivationFunc(16, new BasicFeature[] {query, keyword});
So how can I do this in C++?
// c++ function calling
DerivationFunc(16, /*something like BasicFeature[] {query, keyword} but with the right syntax*/, 2);
You could rewrite the function to take std::initializer_list:
#include <initializer_list>
#include <iostream>
struct BasicFeature {
} query, keyword;
int DerivationFunc(int id, std::initializer_list<BasicFeature> args)
{
std::cout << args.size() << " element(s) were passed.\n";
return id;
}
int main()
{
DerivationFunc(42, { query, keyword });
}
If you are not allowed to use std::initializer_list, I could suggest a little ugly hack:
#include <vector>
#include <iostream>
enum BasicFeature {
query,
keyword
};
template<typename T>
class init_list
{
public:
init_list &operator<<( typename T::value_type value )
{
m_list.push_back(value);
}
operator const T() const { return m_list; }
private:
T m_list;
};
void DeriviationFunc( int id, const std::vector<BasicFeature> &args )
{
std::cout << id << std::endl;
std::cout << args.size() << std::endl;
std::cout << args[0] << std::endl;
}
int main()
{
DeriviationFunc(16, init_list<std::vector<BasicFeature> >() << query << keyword);
return 0;
}

C++11 styled callbacks?

I have a void function inside of a class. In old C++ i'd make a function static taking the class name as a parameter and had my own class which took a static void function + a void* for me to easily call it.
However that feels old school. It also isn't templated which feels like i could be doing more. What is a more modern way of creating callbacks to myclassVar.voidReturnVoidParamFunc
Use std::function and lambdas (or std::bind()) to store callables:
#include <functional>
#include <iostream>
class Test
{
public:
void blah() { std::cout << "BLAH!" << std::endl; }
};
class Bim
{
public:
void operator()(){ std::cout << "BIM!" << std::endl; }
};
void boum() { std::cout << "BOUM!" << std::endl; }
int main()
{
// store the member function of an object:
Test test;
std::function< void() > callback = std::bind( &Test::blah, test );
callback();
// store a callable object (by copy)
callback = Bim{};
callback();
// store the address of a static function
callback = &boum;
callback();
// store a copy of a lambda (that is a callable object)
callback = [&]{ test.blah(); }; // often clearer -and not more expensive- than std::bind()
callback();
}
Result:
BLAH!
BIM!
BOUM!
BLAH!
Compiles and run: http://ideone.com/T6wVp
std::function can be used as any copyiable object, so feel free to store it somewhere as a callback, like in object's member. It also means that you can freely put it in standard containers, like std::vector< std::function< void () > > .
Also note that equivalent boost::function and boost::bind have been available for years.
For an example of passing in parameters to a C++ 11 callback using Lambda's and a vector, see http://ideone.com/tcBCeO or below:
class Test
{
public:
Test (int testType) : m_testType(testType) {};
void blah() { std::cout << "BLAH! " << m_testType << std::endl; }
void blahWithParmeter(std::string p) { std::cout << "BLAH1! Parameter=" << p << std::endl; }
void blahWithParmeter2(std::string p) { std::cout << "BLAH2! Parameter=" << p << std::endl; }
private:
int m_testType;
};
class Bim
{
public:
void operator()(){ std::cout << "BIM!" << std::endl; }
};
void boum() { std::cout << "BOUM!" << std::endl; }
int main()
{
// store the member function of an object:
Test test(7);
//std::function< void() > callback = std::bind( &Test::blah, test );
std::function< void() > callback = std::bind( &Test::blah, test );
callback();
// store a callable object (by copy)
callback = Bim{};
callback();
// store the address of a static function
callback = &boum;
callback();
// store a copy of a lambda (that is a callable object)
callback = [&]{ test.blah(); }; // might be clearer than calling std::bind()
callback();
// example of callback with parameter using a vector
typedef std::function<void(std::string&)> TstringCallback;
std::vector <TstringCallback> callbackListStringParms;
callbackListStringParms.push_back( [&] (const std::string& tag) { test.blahWithParmeter(tag); });
callbackListStringParms.push_back( [&] (const std::string& tag) { test.blahWithParmeter2(tag); });
std::string parm1 = "parm1";
std::string parm2 = "parm2";
int i = 0;
for (auto cb : callbackListStringParms )
{
++i;
if (i == 1)
cb(parm1);
else
cb(parm2);
}
}