invalid use of void expression in context of c++ std::function - c++

In below code snippet while calling call back function "Invalid use of void expression" error
is flashed by the compiler.
#include <iostream>
#include <functional>
using namespace std;
template<class type>
class State {
public:
State(type type1,const std::function<void (type type1 )> Callback)
{
}
};
template <class type>
void Callback(type type1 )
{
//Based on type validation will be done here
}
int main()
{
State<int> obj(10,Callback(10));
return 0;
}
Just want to know what is the wrong here so that same can be addressed .

It seems that you want to pass the Callback<int> function itself, not its return value (which there is none), to the constructor of obj. So do just that:
State<int> obj(10, Callback<int>);
Your current code actually calls Callback(10) first and then tries to take its void "return value" to pass it to the constructor of obj. Passing void is not allowed in C++, which is why the compiler is complaining. (Callback(10) is the "void expresson" here.)

I guess this is what you want
#include <iostream>
#include <functional>
using namespace std;
template<class type>
class State {
public:
State(type type1,const std::function<void (type)> callback)
{
callback(type1);
}
};
template <class type>
void Callback(type type1 )
{
}
int main()
{
State<int> obj(10, Callback<int>);
return 0;
}

I would like to go with lambda expression approach to avoid the confusion :
#include <iostream>
#include <functional>
using namespace std;
template<class type>
class State
{
public:
State( type type1, const std::function<void (type type1 )> Callback)
{
Callback(type1);
}
};
int main()
{
State<int > monitor(10,[] ( int fault) {std::cout<<"Any Message"; });
return 0;
}

Related

Replacing std::bind with lambda with a member function to fill vector of function pointer

I have implemented function pointer list that i want to past the function and the object i want to convert the bind to a lambda function but i failed, any help?
#include <iostream>
#include <functional>
#include <vector>
using namespace std;
class Red {
public:
template <typename F, typename M>
void addToVector(F f, M m)
{
list.push_back(std::bind(f, m));
cout<<"Function added.";
}
std::vector<std::function<void()>> list;
};
class Blue {
public:
Blue()
{
r.addToVector(&Blue::someFunc, this);
}
void someFunc(){
cout<<"Some print.";
}
Red r;
};
int main()
{
Blue b;
return 0;
}
I have tried this list.push_back([=](){ return m->f(); });
I have tried this list.push_back([=](){ return m->f(); });
The correct syntax to call the member function using a pointer to object would be:
//----------------------------vvvvvv------->correct way to call member function using a pointer to object
list.push_back([=](){ return (m->*f)(); });
Working demo

Make int overload a preferable one

Consider following code snippet:
class Foo {
public:
void bar(std::size_t){}
void bar(const char* ){}
};
int main() {
auto foo = Foo{};
foo.bar(0);
}
It produces ambiguous calls errors (check here). But I think from programmer's perspective it is pretty obvious that I want to call overload with std::size_t. My question is if anything can be done so this code does not produce errors and calls size_t overload?
can be done like this in C++ 20
#include <cstdint>
#include <iostream>
#include <type_traits>
class Foo {
public:
template <typename T>
requires std::is_integral_v<T>
void bar(T){
std::cout<<"hello size_T";
}
void bar(const char* ){
std::cout<<"hello";
}
};
int main() {
auto foo = Foo{};
foo.bar(25);
}
In modern c++ (at least c++17), we prefer to pass string_view as argument over const char* for the none owner transfer cases, so a considerable choice:
#include <cctype>
#include <string>
class Foo {
public:
void bar(std::size_t){}
void bar(std::string_view){}
};
int main() {
auto foo = Foo{};
foo.bar(0);
}
Online demo
In below C++ 20, this works well.
#include <iostream>
class Foo {
public:
template <typename T>
void bar(T) {
std::cout << "hello T" << std::endl;
}
void bar(const char* c) {
std::cout << c << std::endl;
}
};
int main() {
auto foo = Foo{};
foo.bar(0);
foo.bar("test.");
}
This works in C++23:
foo.bar(0zu);
and this works pre-C++23:
foo.bar(size_t{0});

How to use string to call function in a class?

I hope to use map library to call a function by a string with the function name, I've tested the following example and everything are working well.
#include <string>
#include <iostream>
using namespace std;
typedef void (*pFunc)();
map<string, pFunc> strFuncMap;
void func1()
{
printf("this is func1!\n");
}
void buildMap()
{
strFuncMap["func1"] = &func1;//
}
void callFunc(const std::string& str)
{
(*strFuncMap[str])();
}
int main()
{
buildMap();
callFunc("func1");
return 0;
}
However, as I define all these things in a class, there is a compiler error occur:
#include <map>
#include <string>
#include <iostream>
using namespace std;
class theClass {
public:
typedef void (*pFunc)();
map<string, pFunc> strFuncMap;
void func1()
{
printf("this is func1!\n");
}
void buildMap()
{
strFuncMap["func1"] = &func1;// a value of type cannot be assigned to an entity of type
}
void callFunc(const std::string& str)
{
(*strFuncMap[str])();
}
};
int main()
{
theClass a;
a.buildMap();
a.callFunc("func1");
return 0;
}
I've tried to solve this problem for a couple of hours. Or is there any other way to use string to call function in a class? I will very appreciate if someone can help me. THANKS!!
Your code doesn't work because func1 is a member function and the syntax for member functions is different.
You need a map of member function pointers (offsets)
typedef void (theClass::*pFunc)();
map<string, pFunc> strFuncMap;
Then you can store the pointer with
strFuncMap["func1"] = &theClass::func1;
And you need an object to call a member function
(this->*strFuncMap[str])();
The final code:
#include <map>
#include <string>
#include <iostream>
using namespace std;
class theClass {
public:
typedef void (theClass::*pFunc)();
map<string, pFunc> strFuncMap;
void func1()
{
printf("this is func1!\n");
}
void buildMap()
{
strFuncMap["func1"] = &theClass::func1;
}
void callFunc(const std::string& str)
{
(this->*strFuncMap[str])();
}
};
int main()
{
theClass a;
a.buildMap();
a.callFunc("func1");
return 0;
}
typedef void (*pFunc)();
This declares pFunc to be the type of function pointers. That is, the type of pointers to functions which exist at the top-level. This excludes member functions, lambda functions, and functors. Consider
using pFunc = std::function<void()>
Now your type will correctly accept anything that can reasonably be interpreted as a callable object. Note that member functions still need to be wrapped in a lambda, since you're closing around this.
strFuncMap["func1"] = [this]() { this->func1(); };

How to use std::function as a template

I am new to the std::function concept.
I need to use std::function in following way
I have a class as follows
class A(string ,bool, string, std::function<void()>)
here the std::function<void()> should take different parameters from different objects.
The parameters will be basically different types of enumerations
for example
1)A a(string ,bool, string, std::function<void(enum xyz)>)
2)A b(string ,bool, string, std::function<void(enum abc)>)
3)A c(string ,bool, string, std::function<void(enum efg)>)
I want to know how should i structure the std::function in class A so that i can pass different enumerations as parameter to the class A objects
You can pass a template type as the std::function parameter. Here's an example:
#include <iostream>
#include <functional>
#include <string>
template <class T>
class Foo
{
public:
Foo(std::function<void(T)> f) : f_{f} {}
void call(T in) { f_(in); }
private:
std::function<void(T)> f_;
};
int main()
{
Foo<double> fd{[] (double d) { std::cout << d << '\n'; }};
fd.call(34.2);
Foo<std::string> fs{[] (std::string s) { std::cout << s << '\n'; }};
fs.call("Test!");
return 0;
}
Output:
34.2
Test!
After looking at your question, this is how you need to use the function.
#include <iostream>
#include <string>
#include <functional> //Need to include for std::function use
using namespace std;
//Declare the ENUM here.
enum ePat {xyz=1,abc,efg,mno};
enum ePat_second {def=1,ghi,jkl,opq};
//utility function you want to pass to std function
template <typename T>
void print(T e)
{
}
template <typename T>
class A
{
public:
//Constructore with std function as one of the argument
A(string ,bool , string, std::function<void(T)>)
{
}
};
int main()
{
//Declare your std function types.
std::function<void(ePat)> xyz_display = print<ePat>;
std::function<void(ePat_second)> def_display = print<ePat_second>;
//Pass it to the object.
A<ePat> a("abc" ,true, "abc",xyz_display);
A<ePat_second> b("def" ,true, "def",def_display);
}

calling functor using function Object tr1::function<>

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();
}