how transfer function from template class - c++

#include <iostream>
#include <windows.h>
#include <string.h>
#include <functional>
#include <stdint.h>
#include <stdio.h>
using namespace std;
template <typename T>
class someclass {
public:
T value;
int sum(int vl1, int vl2) { return vl1 + vl2; };
};
template <typename T>
class someclass2 {
public:
T value;
void print(const std::function<int(int, int)>& func) {
cout << func(3, 4) << '\n';
};
};
int main(int argc, const char **argv)
{
someclass<int> obj1;
someclass2<int> obj2;
obj2.print(obj1.sum);
}
Compiler show error on last line : error C3867: 'someclass::sum': non-standard syntax; use '&' to create a pointer to member

Note that
int sum(int vl1, int vl2) { return vl1 + vl2; };
doesn't use its owner class' member in any way, it safely can be declared static, in that case this code would work.
The problem with this code is that a member function got a different type from standalone function. It's a member of class someclass, so its type is int (someclass::*)(int, int) and to call it you need an instance of that class.
The literal solution in general case is to hide pass of this inside the functor created by lambda expression:
obj2.print( [&](int a, int b)-> int { return obj1.sum(a,b); } );

You can use std::bind to do that
int main(int argc, const char **argv)
{
someclass<int> obj1;
someclass2<int> obj2;
using namespace std::placeholders;
obj2.print(std::bind(&someclass<int>::sum, &obj1, _1, _2));
}

Related

lambda does not name a type in a class in C++ [duplicate]

This question already has answers here:
Why can't member initializers use parentheses?
(2 answers)
can not define and init a class member by Parentheses [duplicate]
(1 answer)
Closed last month.
#include <set>
#include <vector>
#include <string>
#include <iostream>
#include <queue>
auto cmp = [](int a, int b) {
return a > b;
};
class Test {
private:
std::priority_queue<int, std::vector<int>, decltype(cmp)> pq(cmp);
};
int main(int argc, char const *argv[])
{
Test test;
return 0;
}
The output is below:
However, when I use the priority_queue in the main function, it can use the cmp.
Moreover, when I delete the 'cmp' in the 'pq'
auto cmp = [](int a, int b) {
return a > b;
};
class Test {
private:
std::priority_queue<int, std::vector<int>, decltype(cmp)> pq;
};
int main(int argc, char const *argv[])
{
Test test;
return 0;
}
the complier told me:
#include <set>
#include <vector>
#include <string>
#include <iostream>
#include <queue>
auto cmp = [](int a, int b) {
return a > b;
};
int main(int argc, char const *argv[])
{
std::priority_queue<int, std::vector<int>, decltype(cmp)> pq(cmp);
pq.push(1);
std::cout << pq.top() << std::endl;
return 0;
}
I do not know why? I know lambda is a anonymous class, but why in a class it cannot use, in the main function it can use?
Welcome to the wonderful world of the Most Vexing Parse (well, not really, but close enough).
class Test {
private:
std::priority_queue<int, std::vector<int>, decltype(cmp)> pq{cmp};
};
gcc 12 compiles this without any errors. Always use the uniform initialization syntax. It's your friend.

object as key to map becomes const in cpp

can someone please explain why the following code compilation fails with message "passing ‘const apple’ as ‘this’ argument of ‘int apple::foo()’ discards qualifiers", and how to resolve it.
#include <cstdlib>
#include <iostream>
#include <string>
#include <map>
using namespace std;
/*
*
*/
class apple{
private:
int a,b,c,d;
public:
int foo(){
return a+b+c+d;
}
};
class ball{
private:
map<apple,string> mp;
public:
void foo2(){
for(map<apple,string>::iterator it = mp.begin();it!=mp.end();++it){
cout<<it->first.foo()<<endl;
}
}
}
int main(int argc, char** argv) {
return 0;
}
Works for me: (added const at the end of foo() and ; on end of ball class). Class apple is a Key in std::map which is declared as const: typedef pair value_type; so accessing key should be also declared as const.
#include <map>
#include <iostream>
using namespace std;
class apple{
private:
int a,b,c,d;
public:
int foo() const {
return a+b+c+d;
}
};
class ball{
private:
map<apple,string> mp;
public:
void foo2(){
for(map<apple,string>::iterator it = mp.begin();it!=mp.end();++it){
cout<<it->first.foo()<<endl;
}
}
};
int main(int argc, char** argv) {
return 0;
}

using boost::function with instance methods

I am trying to use boost::function with instance methods using the following example
class someclass
{
public:
int DoIt(float f, std::string s1)
{
return 0;
}
int test(boost::function<int(float, std::string)> funct)
{
//Funct should be pointing to DoIt method here
funct(12,"SomeStringToPass");
}
void caller()
{
test(DoIt); //Error : 'someclass::DoIt': function call missing argument list; use '&someclass::DoIt' to create a pointer to member
}
};
Any suggestion on how I could resolve this issue ?
You should use boost::bind:
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <string>
#include <iostream>
using namespace std;
class someclass
{
public:
int DoIt(float f, std::string s1)
{
return 0;
}
int test(boost::function<int(float, std::string)> funct)
{
return funct(5.0, "hello");
}
void caller()
{
cout << test(boost::bind(&someclass::DoIt, this, _1, _2)) << endl;
}
};
int main() {
someclass s;
s.caller();
}

How do I call a class by passing it's object and member function to another function in c++?

How do I execute a member's function by passing the object and the member's function to another function in c++. I do understand the answer to my question is out there; however, I do not know what this is called. So far I created 2 files, exeFunc.h and exeFunc.cpp. Their code consist of:
exeFunc.h
/*
File: exeFunc.h
Header file for exeFunc Library.
*/
#ifndef EXEFUNC_H
#define EXEFUNC_H
#include "mbed.h"
#include "msExtensions.h"
#include "cfExtensions.h"
#include <map>
class exeFunc
{
public:
exeFunc(msExtensions &msExt, cfExtensions &cfExt);
private:
void _splitFuncFromCmd();
void _attachCallback();
msExtensions &_msExt;
cfExtensions &_cfExt;
//FunctionPointer _p;
};
#endif
exeFunc.cpp
/*
File: exeFunc.cpp
Execute functions in other Sensor libraries/classes
Constructor
*/
#include "mbed.h"
#include "ConfigFile.h"
#include "msExtensions.h"
#include "cfExtensions.h"
#include "exeFunc.h"
#include <map>
#include <string>
using namespace std;
exeFunc::exeFunc(msExtensions &msExt, cfExtensions &cfExt) : _msExt(msExt), _cfExt(cfExt)
{
//_cfExt.checkConfigForFirstStart();
//_p.attach(&_cfExt, &cfExtensions::checkConfigForFirstStart);
//_p.call();
}
void exeFunc::_splitFuncFromCmd()
{
}
void exeFunc::_attachCallback()
{
}
I wrote a completed example, may helps
class MyClass
{
public:
MyClass(int b)
:_b(b)
{
}
int Foo(int a)
{
return a * _b;
}
int _b;
};
typedef int (MyClass::*MFP)(int);
int get_result(MyClass* obj, MFP mfp)
{
int r = (obj->*mfp)(5); // 30
return r;
}
int _tmain(int argc, _TCHAR* argv[])
{
MFP mfp = &MyClass::Foo;
MyClass m(6);
get_result(&m, mfp);
return 0;
}
You call it by another function.if you have an independent function.
To be honesty your question is not completely clear.However :
int F(int,int,int);
int g();
//main scope
F(g(),a,b)

C++ error C2662 or how to declare in right way

i get the fallowing error when i compile program:
vandenynas.cpp(19) error C2662: 'skaiciavimas::showst' : cannot convert 'this' pointer from 'const skaiciavimas' to 'skaiciavimas &'
there is my classes:
first.h
#pragma once
#include <iostream>
#include <string>
#include "skaiciavimas.h"
using namespace std;
class vandenynas
{
public:
void duomenys (int i, int a, int a0) const;
string GetName()const;
protected:
skaiciavimas sk;
};
first.cpp
#include "vandenynas.h"
skaiciavimas::v vektorV;
void vandenynas::duomenys (int i, int a, int a0) const
{
switch (i)
{
case 0:
vektorV.x=a-a0;
break;
case 1:
vektorV.y=a-a0;
break;
default:
vektorV.z=a-a0;
break;
}
sk.showst(vektorV);
}
second where is called function.h
#pragma once
#include <iostream>
#include <string>
using namespace std;
class skaiciavimas
{
public:
struct v
{
int x;
int y;
int z;
};
void showst(v st);
};
.cpp
#include "skaiciavimas.h"
void skaiciavimas::showst(v st)
{
cout<<st.x<<" "<<st.y<<" "<<st.z<<endl;
}
can someone tel where is mistake?
The problem is that you declare vandenynas::duomenys as a const function, i.e. it does not change anything in the object. But it calls skaiciavimas::showst which is not declared as const, which is not permissible. If you declare one method as const, all methods it calls, in itself or an object that is a member of the object, also have to be declared as const.
skaiciavimas::showst is not a const member function. Since vandenynas::duomenys is a const member function, all members of this are considered const and therefore skaiciavimas::showst cannot be called.