I have some very simple source code to expose a simple Foo class.
main.cpp:
#include <iostream>
#include <lua.hpp>
#include <LuaBridge.h>
class Foo
{
private:
int number = 0;
public:
void setNumber(const int& newNumber) {number = newNumber;}
int getNumber() {return number;}
};
int main()
{
//Expose the API:
lua_State* L = luaL_newstate();
luaL_openlibs(L);
luabridge::getGlobalNamespace(L)
.beginClass<Foo>("Foo")
.addConstructor<void(*)(void)>()
.addProperty("number", &Foo::getNumber, &Foo::setNumber)
.endClass();
}
Unfortunately, I get this error:
24 error: no matching function for call to ‘luabridge::Namespace::Class<Foo>::addProperty(const char [7], int (Foo::*)(), void (Foo::*)(const int&))’
I don't know what the problem is, but I have to use addProperty otherwise the code doesn't look correct
The template for addProperty:
template <class TG, class TS>
Class <T>& addProperty (char const* name, TG (T::* get) () const, void (T::* set) (TS))
requires that the getter is a const member function.
Changing the getter to:
int getNumber() const { return number; }
removes the error in LuaBridge 2.0
Related
I am trying to use a custom comparator as in the following minimal example:
#include <set>
using namespace std;
struct idComp;
class TestClass
{
public:
int id;
void setId(int i){ id = i; }
int getId(){ return id; }
void test( set<TestClass*, idComp> &s){
//do my stuff
}
void test2(){
set <TestClass*, idComp> s;
}
};
struct idComp
{
bool operator() (TestClass* t1, TestClass* t2) const
{
return t1->getId() < t2->getId();
}
};
int main(int argc, char* argv[])
{
return 0;
}
...but when I try to compile I get the following error relating to the test function:
comp_ref.cpp:12:34: error: ‘idComp’ was not declared in this scope
void test( set<TestClass*, idComp> &s){
^~~~~~
comp_ref.cpp:12:40: error: template argument 2 is invalid
void test( set<TestClass*, idComp> &s){
and this with the addition of test2:
/usr/include/c++/7/bits/stl_tree.h:708:31: error: invalid use of incomplete type ‘struct idComp’
_Rb_tree_impl<_Compare> _M_impl;
Any suggestions of how/where to define idComp so that it is usable by the function test?
Since you have a bit of a circular dependency, you can resolve this by forward-declaring idComp before TestClass:
struct idComp;
class TestClass
{
...
But you can leave the definition of struct idComp where it is.
I am using C++ in native mode with Visual Studio 2017 and I am trying to compile and run the example code found at Debugging a Parallel Application in Visual Studio.
For the record, I program in C not C++. I am clueless when it comes to method declarations (among many other things). I suspect correcting the error is simple but, I simply don't know how.
In other words, I am currently RTFineM. I simply copied and pasted the example given in the url above and ran into 2 problems. First it complained about something being deprecated but a simple define took care of that problem. Second it complained about not being able to convert a type into another as stated in the title.
The RunFunc class causing the problem is declared as follows:
class RunFunc
{
Func& m_Func;
int m_o;
public:
RunFunc(Func func,int o):m_Func(func),m_o(o)
{
};
void operator()()const
{
m_Func(m_o);
};
};
My question/request is: how does the declaration of RunFunc need to be in order for the example to compile and run properly ?
Thank you, much appreciate the help.
In this constructor
RunFunc(Func func,int o):m_Func(func),m_o(o)
{
};
the prameter Func func is adjusted by the compiler to the type Func *func. On the other hand the data member m_Func is declared as a referenced type.
Func& m_Func;
And the error message says about incompatibility of the types.
C2440 cannot convert from 'void (_cdecl*)(int)' to 'void(_cdecl&)(int)
Try to declare the constructor like
RunFunc(Func &func,int o):m_Func(func),m_o(o)
{
};
Or declare the data member like
Func *m_Func;
without changing the constructor.
Here are two demonstrative programs
#include <iostream>
typedef void Func( int );
class RunFunc
{
Func& m_Func;
int m_o;
public:
RunFunc(Func &func,int o):m_Func(func),m_o(o)
{
};
void operator()()const
{
m_Func(m_o);
};
};
int main() {
return 0;
}
and
#include <iostream>
typedef void Func( int );
class RunFunc
{
Func *m_Func;
int m_o;
public:
RunFunc(Func func,int o):m_Func(func),m_o(o)
{
};
void operator()()const
{
m_Func(m_o);
};
};
int main() {
return 0;
}
In your code you are tyring to bound a reference to a temporary, namely to copy of argument passed to the constructor. You can try to run the following code snippet to see the difference:
struct Func {
int _i;
void operator()(int i) { cout << i*_i << endl; }
};
class RunFunc
{
Func& m_Func;
int m_o;
public:
RunFunc(Func &func, int o) :m_Func(func), m_o(o)
// RunFunc(Func func, int o) :m_Func(func), m_o(o)
{
};
void operator()()const
{
m_Func(m_o);
};
};
int main() {
Func f{ 5 };
RunFunc rf(f, 2);
rf();
return 0;
}
This is a legacy approach. You can use standard library functor and binder instead. For example:
#include <functional>
#include <iostream>
static void my_callback(int i) {
std::cout<< i << std::endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
std::function<void()> functor;
functor = std::bind(my_callback, 1);
functor();
return 0;
}
I try to implement Scott Mayer book code example, the example is about calling functor through function object
the header file gameCharachter.h
#ifndef GAMECHARACTER_H
#define GAMECHARACTER_H
#include <iostream>
#include <typeinfo>
using namespace std;
#include <tr1/functional>
class GameCharacter;
int defaultHealthCalc(const GameCharacter& gc);
class GameCharacter
{
public:
typedef std::tr1::function<int (const GameCharacter&)> HealthCalcFunc;
explicit GameCharacter(HealthCalcFunc hcf = defaultHealthCalc)
: healthFunc(hcf)
{
}
~GameCharacter()
{
}
int healthValue() const
{
return healthFunc(*this);
}
private:
HealthCalcFunc healthFunc;
};
class EyeCandyCharacter: public GameCharacter // another character
{
public:
explicit EyeCandyCharacter(HealthCalcFunc hcf = defaultHealthCalc)
: GameCharacter(hcf)
{
cout<<typeid(*this).name()<<"::"<<__FUNCTION__<<""<<endl;
}
};
struct HealthCalculator
{
/*explicit*/ HealthCalculator()
{
}
int operator()(const GameCharacter& gc) const // calculation function
{
cout<<typeid(*this).name()<<"::"<<__FUNCTION__<<""<<endl;
return 0;
}
};
#endif // GAMECHARACTER_H
the main.cpp is :
#include "gamecharacter.h"
int main()
{
EyeCandyCharacter ecc1(HealthCalculator());
ecc1.healthValue();
}
why function<> object refuse to call the operator() function in healthvalue()
EyeCandyCharacter ecc1(HealthCalculator());
declares a function called ecc1 that takes an argument of type "pointer to function taking no arguments and returning a HealthCalculator" and returns a EyeCandyCharacter. I assume that this isn't your intent.
this is the correct call , it should be called by bind
#include "gamecharacter.h"
int main()
{
HealthCalculator hc;
EyeCandyCharacter ecc1(std::tr1::bind(&HealthCalculator::operator(),hc,tr1::placeholders::_1));
ecc1.healthValue();
}
I am new to c++. So I'm trying to do something that is trivial but cannot figure out how.
I have a Class called Method:
class Method{
private:
std::string nameMethod;
Func f;
public:
Method(std::string name,Func fun){
nameMethod=name;
f=fun;
};
I want to create an Object of type Method called methDaniel which has
string nameMethod = addDaniel.
f = to a function that prints "Daniel".
How do I do this in the main.cpp file?
#include "Method.h"
using namespace std;
typedef void (*t_somefunc)();
void addDaniel(){
cout<<"Daniel";
}
int main(){
addDaniel();
t_somefunc afunc = &addDaniel;
Method* methDaniel = new Method("addDaniel",afunc);
}
Move the typedef for defining t_somefunc to "Method.h".
Change the type of f from Fun to t_somefunc.
Method.h:
typedef void (*t_somefunc)();
class Method{
private:
std::string nameMethod;
t_somefunc f;
public:
Method(std::string const& name, t_somefunc fun) : nameMethod(name), f(fun){}
Then, in main:
Method* methDaniel = new Method("addDaniel", addDaniel);
I am trying to create a generic function map using templates.The idea is to inherit from this generic templated class with a specific function pointer type. I can register a function in the global workspace, but I'd rather collect all the functions together in the derived class and register these in the constructor. I think I am almost here but I get a compile error. Here is a stripped down version of my code:
#include <iostream>
#include <string>
#include <map>
#include <cassert>
using namespace std;
int f(int x) { return 2 * x; }
int g(int x) { return -3 * x; }
typedef int (*F)(int);
// function factory
template <typename T>
class FunctionMap {
public:
void registerFunction(string name, T fp) {
FunMap[name] = fp;
}
T getFunction(string name) {
assert(FunMap.find(name) != FunMap.end());
return FunMap[name];
}
private:
map<string, T> FunMap;
};
// specific to integer functions
class IntFunctionMap : public FunctionMap<F> {
public:
int f2(int x) { return 2 * x; }
int g2(int x) { return -3 * x; }
IntFunctionMap() {
registerFunction("f", f); // This works
registerFunction("f2", f2); // This does not
}
};
int main()
{
FunctionMap<F> fmap; // using the base template class directly works
fmap.registerFunction("f", f);
F fun = fmap.getFunction("f");
cout << fun(10) << endl;
return 0;
}
The error I get is:
templatefunctions.cpp: In constructor ‘IntFunctionMap::IntFunctionMap()’:
templatefunctions.cpp:33: error: no matching function for call to ‘IntFunctionMap::registerFunction(const char [3], <unresolved overloaded function type>)’
templatefunctions.cpp:15: note: candidates are: void FunctionMap<T>::registerFunction(std::string, T) [with T = int (*)(int)]
Juan's answer is correct: member functions have an implicit first parameter, which is a pointer to the type of which they are a member. The reason your code fails to compile is that your map supports function pointers with type int (*)(int), but the type of f2 is int (IntFunctionMap::*)(int).
In the specific case that you show here, you can use std::function, which implements types erasure, to present free functions and member functions as the same type. Then you could do what you are trying to do. Note: this requires C++11.
#include <iostream>
#include <string>
#include <map>
#include <cassert>
#include <function>
#include <bind>
using namespace std;
int f(int x) { return 2 * x; }
int g(int x) { return -3 * x; }
typedef std::function<int (int)> F;
// function factory
template <typename T>
class FunctionMap {
public:
void registerFunction(string name, T fp) {
FunMap[name] = fp;
}
T getFunction(string name) {
assert(FunMap.find(name) != FunMap.end());
return FunMap[name];
}
private:
map<string, T> FunMap;
};
// specific to integer functions
class IntFunctionMap : public FunctionMap<F> {
public:
int f2(int x) { return 2 * x; }
int g2(int x) { return -3 * x; }
IntFunctionMap() {
registerFunction("f", f); // This works
registerFunction("f2", std::bind(&f2, this, _1)); // This should work, too!
}
};
int main()
{
FunctionMap<F> fmap; // using the base template class directly works
fmap.registerFunction("f", f);
F fun = fmap.getFunction("f");
cout << fun(10) << endl;
return 0;
}