I have the following code:
#include<iostream>
using namespace std;
void saludo();
void despedida();
int main(){
void (*Ptr_Funciones[2])() = {saludo, despedida};
(Ptr_Funciones[0])();
(Ptr_Funciones[1])();
return 0;
}
void saludo(){
cout<<"\nHola mundo";
}
void despedida(){
cout<<"\nAdios mundo"<<endl<<endl;
}
Based on this, a few questions were generated which I investigated before asking but did not fully understand.
The questions are:
How do I make an array of functions, if they are of a different type?
I know that in C ++ this notation is used for undetermined parameters: (type var ...) The
thing is, I don't know how to interact with them inside the function.
If questions 1 and 2 are possible, can these points be combined when creating function
arrays?
I really have investigated. But I can't find much information, and the little I did find I didn't understand very well. I hope you can collaborate with me.
Thank you very much.
How do I make an array of functions, if they are of a different type?
You can, but you don't want to. It doesn't make semantic sense. An array is a collection of the same kind of thing. If you find that you need to make a collection of different kinds of things, there are several data structures at your disposal.
I know that in C++ this notation is used for undetermined parameters: (type var ...) The thing is, I don't know how to interact with them inside the function.
Here's how you can use the syntax you mention. They're called variadic functions.
If questions 1 and 2 are possible, can these points be combined when creating function arrays?
Erm, I can't imagine why/when a combination of these two would be needed, but out of intellectual curiosity, awayyy we go...
A modified version of the code from the reference link above that kinda does what you want (i've used a map instead of an array, cuz why not):
#include <iostream>
#include <cstdarg>
#include <unordered_map>
template<typename T>
using fooptr = void (*) (T *t...);
struct A {
const char *fmt;
A(const char *s) :fmt{s} {}
};
struct B : public A {
B(const char *s) : A{s} {}
};
void simple_printf(A *a...)
{
va_list args;
auto fmt = a->fmt;
va_start(args, a);
while (*fmt != '\0') {
if (*fmt == 'd') {
int i = va_arg(args, int);
std::cout << i << '\n';
} else if (*fmt == 'c') {
// note automatic conversion to integral type
int c = va_arg(args, int);
std::cout << static_cast<char>(c) << '\n';
} else if (*fmt == 'f') {
double d = va_arg(args, double);
std::cout << d << '\n';
}
++fmt;
}
va_end(args);
}
int main()
{
A a{"dcff"};
B b{"dcfff"};
std::unordered_map<size_t, fooptr<struct A>> index;
index[1] = simple_printf;
index[5] = simple_printf;
index[1](&a, 3, 'a', 1.999, 42.5);
index[5](&b, 4, 'b', 2.999, 52.5, 100.5);
}
This still really doesn't do what you wanted (i.e., give us the ability to choose from different functions during runtime). Bonus points if you understand why that's the case and/or how to fix it to do what you want.
Use a type alias to make things readable:
Live On Coliru
using Signature = void();
Signature* Ptr_Funciones[] = { saludo, despedida };
Prints
Hola mundo
Adios mundo
More flexible:
You can also use a vector:
Live On Coliru
#include <iostream>
#include <vector>
using namespace std;
void saludo() { cout << "\nHola mundo"; }
void despedida() { cout << "\nAdios mundo" << endl << endl; }
int main() {
vector Ptr_Funciones = { saludo, despedida };
Ptr_Funciones.front()();
Ptr_Funciones.back()();
}
Prints the same.
More Flexibility: Calleables of Different Types
To bind different types of functions, type-erasure should be used. std::function helps:
Live On Coliru
#include <iostream>
#include <functional>
#include <vector>
using namespace std;
void saludo(int value) { cout << "\nHola mundo (" << value << ")"; }
std::string despedida() { cout << "\nAdios mundo" << endl << endl; return "done"; }
int main() {
vector<function<void()>>
Ptr_Funciones {
bind(saludo, 42),
despedida
};
Ptr_Funciones.front()();
Ptr_Funciones.back()();
}
Prints
Hola mundo (42)
Adios mundo
Here is one solution that is possible, whether it fits your needs I'm not sure.
#include <Windows.h>
#include <iostream>
void saludo()
{
std::cout << "\nHola mundo" << std::endl;;
}
void despedida()
{
std::cout << "\nAdios mundo" << std::endl;
}
void* fnPtrs[2];
typedef void* (VoidFunc)();
int main()
{
fnPtrs[0] = saludo;
fnPtrs[1] = despedida;
((VoidFunc*)fnPtrs[0])();
((VoidFunc*)fnPtrs[1])();
std::getchar();
return 0;
}
Related
Is it possible to create a vector that has functions pushed back?
I've tried doing something with pointers, but it only works with functions without parameters.
For example,
#include <iostream>
#include <vector>
using namespace std;
void printInt();
int main()
{
vector<void (*)()> functionStack;
functionStack.push_back(printInt);
(*functionStack[0])();
}
void printInt()
{
cout << "function works!" << 123 << endl;
}
That works, but not what I need.
The correct version of that would be a function that has parameters: void printInt(int a) and you could call it with different values like 4 or -1 but from the vector functionStack.
It's probably more complex if the functions in the vector are with different parameters, so let's assume that every function has the same type and amount of parameters.
This:
void (*)()
is a function pointer taking no arguments. So change it to take the desired argument.
void (*)(int)
Like so:
void printInt(int x)
{
cout << "function works!" << x << endl;
}
int main()
{
vector<void (*)(int)> functionStack;
functionStack.push_back(printInt);
(*functionStack[0])(123);
}
You are correct in saying the functions must have the same type and number of parameters for this to be valid.
You basically had it already.
#include <iostream>
#include <vector>
using namespace std;
void printInt(int a);
int main()
{
// Just needed the parameter type
vector<void (*)(int)> functionStack;
// Note that I removed the () from after the function
// This is how we get the function pointer; the () attempts to
// invoke the function
functionStack.push_back(printInt);
(*functionStack[0])(42);
}
void printInt(int a)
{
cout << "function works! " << a << endl;
}
This is also a situation where std::function might be beneficial as well.
#include <iostream>
#include <functional>
#include <vector>
using namespace std;
void printInt(int a);
int main()
{
// Similar syntax, std::function allows more flexibility at a
// lines of assembly generated cost. But it's an up-front cost
vector<std::function<void(int)>> functionStack;
functionStack.push_back(printInt);
// I don't have to de-reference a pointer anymore
functionStack[0](42);
}
void printInt(int a)
{
cout << "function works! " << a << endl;
}
I'm looking for a way to store function pointers in a container like a vector. This is possible if all the functions have the same parameters but can I do if the functions have individually unique parameters?
#include <iostream>
#include <vector>
using namespace std;
void sayHi() {
cout << "Hi" << endl;
}
void sayNum(int num) {
cout << num << endl;
}
int main() {
vector<void(*)()> funcs; // vector of 0 argument functions
funcs.push_back(sayHi);
funcs.push_back(sayNum); // can't store sayNum because it takes arguments
}
Note that I can't use std::function or std::bind because VS2013 doesn't have them and I'd rather not use the boost library. The solution must be allow the possibility to iterate through the vector of function pointers and execute each one with some valid arguments.
Forgive my potential ignorance about how function pointers work, I'm very used to doing this sort of thing in Javascript in one statement :P
Made the mistake of not including as I couldn't see it mentioned in anybody's code examples but it's probably just me being bad at C++.
Not going to accept my own answer, but thought I'd post my code just in the interests of anybody who might find it useful.
#include <iostream>
#include <vector>
#include <functional>
using namespace std;
typedef std::vector<std::function<void(void)>> f_list;
f_list f1;
void _sayHi();
void _sayNum(int num);
void sayHi() {
f1.push_back(
std::bind(&_sayHi)
);
}
void sayNum(int num) {
f1.push_back(
std::bind(&_sayNum, num)
);
}
void _sayHi() {
cout << "hi" << endl;
}
void _sayNum(int num) {
cout << num << endl;
}
int main() {
sayHi();
sayNum(5);
for (int i = 0; i < f1.size(); i++) {
f1.at(i)(); // will execute desired functions
}
}
VS 2103 has std::function, std::bind and lambdas. Simply use them.
I've seen variants of this question asked, but they usually involve functions returning the same type. Here is my code:
#include <iostream>
#include <functional>
#include <map>
using namespace std;
void checkType(int x){
cout << "we got an int: " << x << endl;
}
void checkType(float x){
cout << "we got a float: " << x << endl;
}
int getInt(){
return 1;
}
float getFloat(){
return -101.23f;
}
int main(){
map<string, function<float()> > myMap({
{"int", getInt},
{"float", getFloat}
});
checkType(myMap["int"]());
checkType(myMap["float"]());
return 1;
}
The goal here is to call different versions of an overloaded function (checkType) depending on what the mapped function returns. Obviously the checkType(float) function ends up getting called twice because my map thinks all its functions return floats.
Is there a good way to do this? And is it at all good practice? I've found a different solution, but I think if something like this is legitimate it could be pretty sexy.
As you already found out, the way you implemented it, is not going to work, since the functions stored in map are returning float.
A proper way is to use type erasure, but if you use void* you have to take care of proper casting. Another option is to use boost::any, or QVariant.
This example uses const void* to erase types :
#include <iostream>
#include <functional>
#include <map>
using namespace std;
void callForInt(const void* x){
const int* realX = static_cast < const int* >( x );
cout << "we got an int: " << *realX << endl;
}
void callForFloat(const void* x){
const float* realX = static_cast < const float* >( x );
cout << "we got a float: " << *realX << endl;
}
int main(){
map<string, function<void(const void*)> > myMap({
{"int", callForInt},
{"float", callForFloat}
});
const int v1 = 1;
const float v2 = -101.23f;
myMap["int"](&v1);
myMap["float"](&v2);
}
I have tried multiple google searches and help guides, but I'm out of ideas on this one. I have a function pointer that I am using as an argument for another function. Both functions are within the same class. However, I keep getting type conversion errors. I'm sure this is just a syntax problem, but I can't understand what the correct syntax is. Here is a simplified version of my code:
Header File
#ifndef T_H
#define T_H
#include <iostream>
#include <complex>
namespace test
{
class T
{
public:
T();
double Sum(std::complex<double> (*arg1)(void), int from, int to);
int i;
std::complex<double> func();
void run();
};
}
#endif // T_H
Source File
#include "t.h"
using namespace test;
using namespace std;
//-----------------------------------------------------------------------
T::T()
{
}
//-----------------------------------------------------------------------
double T::Sum(complex<double>(*arg1)(void), int from, int to)
{
complex<double> out(0,0);
for (i = from; i <= to; i++)
{
out += arg1();
cout << "i = " << i << ", out = " << out.real() << endl;
}
return out.real();
}
//-----------------------------------------------------------------------
std::complex<double> T::func(){
complex<double> out(i,0);
return out;
}
//-----------------------------------------------------------------------
void T::run()
{
Sum(&test::T::func, 0, 10);
}
Whenever I try to compile, I get the following error:
no matching function for call to 'test::T::Sum(std::complex<double> (test::T::*)(),int,int)'
note: no known conversion for argument 1 from 'std::complex<double> (test::T::*)()' to 'std::complex<double>(*)()'
Any advice appreciated. Or at least a link to a thorough site on how to use function pointers. I am using Qt Creator 2.6.2, compiling with GCC.
Your Sum function expects pointer to a function. And then you try to call it with a pointer to a member function. Learn about pointers to members.
The code itself is a bit messy, I'll only correct the grammer to make it work.
firstly, you shall change the function prototype from
double Sum(std::complex<double> (*arg1)(void), int from, int to);
to
double Sum(std::complex<double> (T::*arg1)(void), int from, int to);
Meaning that it is a pointer to class T's member.
Then, when calling the function, you cant just arg1(),
for (i = from; i <= to; i++)
{
out += arg1();
cout << "i = " << i << ", out = " << out.real() << endl;
}
you have to use (this->*arg1)();
for (i = from; i <= to; i++)
{
out += (this->*arg1)();
cout << "i = " << i << ", out = " << out.real() << endl;
}
How to pass functions as arguments in C++? In general, use a template, unless you have very compelling reasons not do it.
template<typename Func>
void f(Func func) {
func(); // call
}
On the call side, you can now throw in a certain amount of objects (not just pointers to functions):
Functors;
struct MyFunc {
void operator()() const {
// do stuff
}
};
// use:
f(MyFunc());
Plain functions:
void foo() {}
// use
f(&foo) {}
Member functions:
struct X {
void foo() {}
};
// call foo on x
#include <functional>
X x;
func(std::bind(&X::foo, x));
Lambdas:
func([](){});
If you really want a compiled function and not a template, use std::function:
void ff(std::function<void(void)> func) {
func();
}
Firstly,I want to inform you that my overall/main target is to execute certain functions using their function name(string) as an argument,I defined a function as below:
(I want to generate a unique number for each string data that I inserted as argument to a function)
#include <iostream>
#include <string>
#include <hash_set>
using namespace std;
void Func_Execution(string &s){
int k=stdext::hash_value(s);
#if(_MSC_VER ==1500)
switch (k)
{
case -336300864: GETBATTERYCALLSIGNS();
break;
case -1859542241:GETGUNIDS();
break;
case 323320073:Foo(); // here int k=323320073 for string s="Foo"
break;
case 478877555:Bar();
break;
defalut :Exit();
break;
}
#endif
}
Here I call Func_Execution function as below:
void main(){
string s="Foo";
Func_Execution(s);
}
I want to know that is there any efficient(considering perfomance/time consuming) and effective mechanism to generate a unique numerical value for certain string(character pattern) rather than using stdext::hash_value() function?(Also notice I want to implement switch-case too)
Have you considered something like
#include <functional>
#include <iostream>
#include <unordered_map>
#include <string>
using std::cout;
using std::endl;
using std::function;
using std::string;
using std::unordered_map;
class Registry {
public:
static void Execute(const string& function) {
if (functions_.find(function) != functions_.end()) {
functions_[function]();
}
}
static int Register(const string& function_name, function<void()> f) {
functions_.emplace(function_name, f);
return functions_.size();
}
static void Dump() {
for (auto& i : functions_) {
cout << i.first << endl;
}
}
private:
Registry() {};
static unordered_map<string, function<void()>> functions_;
};
unordered_map<string, function<void()>> Registry::functions_;
#define REGISTER_FUNCTION(F) \
namespace { \
const int REGISTERED__##F = Registry::Register(#F, &F); \
}
void foo() {
cout << "foo" << endl;
}
REGISTER_FUNCTION(foo);
void bar() {
cout << "bar" << endl;
}
REGISTER_FUNCTION(bar);
int main() {
Registry::Execute("foo");
Registry::Execute("foo");
Registry::Execute("unknown");
Registry::Dump();
return 0;
}
It should serve well for your use case. I just hacked it together, there's probably a bug somewhere, but it compiles and runs (c++11).
Don't use hash_value() for fingerprinting (which is what you are describing). If you really know all your possible strings ahead of time, use your own perfect hash function and then measure the results to see if it is worth it.