Related
This is a bit of a contrived example, but its the least amount of code to reproduce my question.
Here I am passing a function callback, and the result is converted to a string and pushed into a vector. This works great for any type with a to_string implementation. (Im using function pointers instead of std::function because some of the function are coming from third party C libraries)
#include <vector>
#include <string>
template<typename R>
void Example(std::vector<std::string> &vec, R (*func)()) {
auto r = func();
vec.push_back(std::to_string(r));
}
int main(int argc, char **argv ) {
std::vector<std::string> vec;
Example(vec, static_cast<int(*)()>([]() -> int{
return 0;
}));
Example(vec, static_cast<double(*)()>([]() -> double{
return 0.0;
}));
}
The one special case however is void. In that case I don't want anything pushed to the vector.
// This obviously does not compile.
Example(vec, static_cast<void(*)()>([](){
auto a = 0;
}));
I know I can overload Example, i.e.
void Example(std::vector<std::string> &vec, void (*func)()) {
func();
}
But in my real world application, Example is MUCH more complex and overloading results in a lot of copy pasted code. I attempted to use type_traits But couldn't get that to work.
Is there another approach that I am missing?
if constexpr allows you to conditionally compile code, given that the condition depends on a template parameter. This requires C++17 for if constexpr and #include<type_traits> for the std::is_same_v type trait.
template<typename R>
void Example(std::vector<std::string> &vec, R (*func)()) {
if constexpr(std::is_same_v<R, void>) {
func();
} else {
auto r = func();
vec.push_back(std::to_string(r));
}
}
Not to sure how to name this question because the problem itself is looking for a construct of which I don´t know its name.
The problem is I am dealing with programs whose control flow depends greatly of data.
For example I created a MIPS simulator which implemented a list of more than 50 instructions, each implemented on its own and everything governed by a huge switch case
switch (function){ //Function is an int, each function (eg SLL) is
case 0: //associated with one
if (state->debug_level > 0){
fprintf(state->debug_out, "SLL\n");
}
step_err = SLL(state, rs, rt, rd, sa);
break;
case 2:
if (state->debug_level > 0){
fprintf(state->debug_out, "SRL\n");
}
step_err = SRL(state, rs, rt, rd, sa);
break;
case 3:
if (state->debug_level > 0){
fprintf(state->debug_out, "SRA\n");
}
//
I have been told that this could have been implemented using function pointers, but to do so what I am looking for is a way of relating data of any kind, say a string to other data, say an integer. I am aware of maps but wouldn't want to push back each pair. I am looking for some sort of array like syntax I think if seen before which might look something similar to this:
¿type? function_codes[]{
0, "SLL";
2, "SRL";
3, "SRA";
...
}
I am not looking for a solution to this problem but a generic approach to introducing quick relationships between data and using this to modify control flow.
EDIT AFTER ANSWERS
What I was actually looking for but I didnt know was indeed maps but in particular its initialization syntax similar to an array (see accepted answer). This used with function pointers did the required job.
As you guessed, function pointers are in fact a good way to do this. Since you specify that you don't want to use a Map, this is how you would implement your integer-based function dispatch using an array of function pointers. Note that since I don't know the type signature of your MIPS functions (SLL, SRL, etc.) I've used dummy placeholder type names.
typedef ret_t (*mips_func)(arg1_t, arg2_t, arg3_t, arg4_t, arg5_t);
mips_func function_codes[] = {
&SLL,
&SRL,
&SRA,
...
};
//...Later, in the part of your code that used to contain the big switch statement
step_err = (*function_codes[function])(state, rs, rt, rd, sa);
The syntax &SLL gets a pointer to the function SLL, which I assume is already in scope because you can call it directly from your switch statement.
Note that this assumes the numeric codes for the functions are a continuous sequence of integers from 0 to [max code value]. If some numeric codes are unused, then you will either need to leave explicit gaps in your array (by placing a NULL pointer in one or more entries) or use std::map<int, mips_func> so that you can use arbitrary non-continuous integer values as keys to functions. Fortunately, using a Map still doesn't require push_backing each element, since C++ now has initializer lists. The same code using a Map would look like this:
typedef ret_t (*mips_func)(arg1_t, arg2_t, arg3_t, arg4_t, arg5_t);
std::map<int, mips_func> function_codes = {
{0, &SLL},
{2, &SRL},
{4, &SRA},
...
};
//Using the Map looks exactly the same, due to its overloaded operator[]
step_err = (*function_codes[function])(state, rs, rt, rd, sa);
For simplify you can use associative containers. If the order is important then use std::map, or std::unordered_map in the other case.
And you can use syntax similar to the desired
std::map<size_t, std::string> codes_map = decltype(codes_map) {
{ 0, "val1" },
{ 1, "val2" }
};
You could group the data as static members w/ the same name across structs, then use templates to access them generically:
struct A { auto call() const { return "((1))"; }; static const char * name; };
struct B { auto call() const { return "{{2}}"; }; static const char * name; };
struct C { auto call() const { return "<<3>>"; }; static const char * name; };
// n.b. these `T...` have: `sizeof(T) == ... == sizeof(empty_struct)`
const char * A::name = "A";
const char * B::name = "B";
const char * C::name = "C";
boost::variant (and the soon to be implemented std::variant) implements a type-safe union, which provides a very clean and efficient way of using these structs as values:
#include <cstdio>
#include <vector>
#include <boost/variant.hpp>
int main()
{
std::vector<boost::variant<A, B, C>> letters{A{}, B{}, C{}, B{}, A{}};
auto visitor = [](auto x) { std::printf("%s(): %s\n", x.name, x.call()); };
for (auto var : letters) { boost::apply_visitor(visitor, var); }
}
Demo
It seems like you have two problems: the flow-control issue (dispatch) and the map issue (an implementation note). I get that the program flow is nonstatic and unknowable at compile-time… but so is the map static? For static maps I get a lot of mileage out of using a traits-ish approach to create a compile-time mapping. Here’s a quick example mapping file suffixes to Objective-C enum constants:
namespace objc {
namespace image {
template <std::size_t N> inline
constexpr std::size_t static_strlen(char const (&)[N]) { return N; }
template <NSBitmapImageFileType t>
struct suffix_t;
#define DEFINE_SUFFIX(endstring, nstype) \
template <> \
struct suffix_t<nstype> { \
static constexpr std::size_t N = static_strlen(endstring); \
static constexpr char const str[N] = endstring; \
static constexpr NSBitmapImageFileType type = nstype; \
};
DEFINE_SUFFIX("tiff", NSTIFFFileType);
DEFINE_SUFFIX("bmp", NSBMPFileType);
DEFINE_SUFFIX("gif", NSGIFFileType);
DEFINE_SUFFIX("jpg", NSJPEGFileType);
DEFINE_SUFFIX("png", NSPNGFileType);
DEFINE_SUFFIX("jp2", NSJPEG2000FileType);
template <NSBitmapImageFileType nstype>
char const* suffix_value = suffix_t<nstype>::str;
}
}
… see how that works? the nice part is that using it has no runtime overhead, which if your map is static, you can use something like that.
For dynamic flow-control and dispatch, function pointers work; that is what happens automatically if you use polymorphic classes and virtual functions but it seems like you have an architecture in place already that may not be amenable to being redone with such high-modernist architectural notions. I like c++11 lambdas as they solve like 90% of my problems in this arena. Perhaps you can elablrate (I will amend my answer)!
If you only have a small number of indices to support, from 0 to 50, you'll get the best performance if you put your function pointers in an array and not a map.
The syntax is also short:
#include <iostream>
#include <functional>
static void f0() {
std::cout << "f0\n";
}
static void f1() {
std::cout << "f1\n";
}
void main()
{
std::function<void()> f[2] = { f0, f1 };
f[0](); // prints "f0"
f[1](); // prints "f1"
}
Or, if you prefer classes over functions:
#include "stdafx.h"
#include <iostream>
class myfunc {
public:
virtual void run() abstract;
virtual ~myfunc() {}
};
class f0 : public myfunc {
public:
virtual void run() {
std::cout << "f0\n";
}
};
class f1 : public myfunc {
public:
virtual void run() {
std::cout << "f1\n";
}
};
void main()
{
myfunc* f[2] = { new f0(), new f1() };
f[0]->run(); // prints "f0"
f[1]->run(); // prints "f1"
for (int i = 0; i < sizeof(f) / sizeof(f[0]); ++i)
delete f[i];
}
Given some definitions
#include <iostream>
#include <iterator>
#include <algorithm>
#include <stdexcept>
#include <map>
using namespace std;
struct state{
int debug_level = 1;
const char* debug_out = "%s";
} s;
// some functions to call
void SLL(state& s, int, int, int, int){
cout << "SLL";
}
void SLR(state& s, int, int, int, int){
cout << "SLR";
}
void SLT(state& s, int, int, int, int){
cout << "SLT";
}
You can use a Map
auto mappedname2fn = map<string, delctype(SLL)*>{
{"SLL", SLL},
{"SLR", SLR}
};
// call a map function
mappedname2fn["SLR"](s, 1, 2, 3, 4);
If you don't want a map you can use a pre-sorted array for a binary search
Here's a binary search of an array of name, function pairs
template<typename P, int N, typename ...T>
auto callFn(P(&a)[N], string val, T&&... params){
auto it = lower_bound(a, a+N, make_pair(val, nullptr),
[](auto& p1, auto& p2){return p1.first < p2.first;});
if(it==(a+N) || val<it->first) throw logic_error("not found");
return it->second(forward<T>(params)...);
}
So you can set up an array and use that:-
// array sorted in alphabetical order for binary search to work
pair<string, decltype(SLL)*> name2fn[] = {
{"SLL", SLL},
{"SLR", SLR},
{"SLT", SLT}
};
void callFn(string name, state& s, int a, int b, int c, int d){
try{
callFn(name2fn, name, s, a, b, c, d);
}
catch(exception& e){
cout << e.what();
}
}
// call it
callFn("SLL", s, 1, 2, 3, 4);
Abstract
I have a class that stores a optimization problem and runs a solver on that problem.
If the solver fails I want to consider a sub-problem and solve using the same solver (and class).
Introduction
An optimization problem is essencially a lot of (mathematical) functions. The problem functions are defined outside the class, but the sub-problem functions are defined inside the class, so they have different types (e.g. void (*) and void (MyClass::*).
At first I thought that I could cast the member function to the non-member pointer-to-function type, but I found out that I cannot. So I'm searching for some other way.
Example Code
An example code to simulate my issue:
#include <iostream>
using namespace std;
typedef void (*ftype) (int, double);
// Suppose foo is from another file. Can't change the definition
void foo (int n, double x) {
cout << "foo: " << n*x << endl;
}
class TheClass {
private:
double value;
ftype m_function;
void print (int n, double x) {
m_function(size*n, value*x);
}
public:
static int size;
TheClass () : value(1.2), m_function(0) { size++; }
void set_function (ftype p) { m_function = p; }
void call_function() {
if (m_function) m_function(size, value);
}
void call_ok_function() {
TheClass ok_class;
ok_class.set_function(foo);
ok_class.call_function();
}
void call_nasty_function() {
TheClass nasty_class;
// nasty_class.set_function(print);
// nasty_class.set_function(&TheClass::print);
nasty_class.call_function();
}
};
int TheClass::size = 0;
int main () {
TheClass one_class;
one_class.set_function(foo);
one_class.call_function();
one_class.call_ok_function();
one_class.call_nasty_function();
}
As the example suggests, the member function can't be static. Also, I can't redefine the original problem function to receive an object.
Thanks for any help.
Edit
I forgot to mention. I tried changing to std::function, but my original function has more than 10 arguments (It is a Fortran subroutine).
Solution
I made the change to std::function and std::bind as suggested, but did not went for the redesign of a function with more 10 arguments. I decided to create an intermediate function. The following code illustrates what I did, but with fewer variables. Thanks to all.
#include <iostream>
#include <boost/tr1/functional.hpp>
using namespace std;
class TheClass;
typedef tr1::function<void(int *, double *, double *, double *)> ftype;
// Suppose foo is from another file. Can't change the definition
void foo (int n, int m, double *A, double *x, double *b) {
// Performs matrix vector multiplication x = A*b, where
// A is m x n
}
void foo_wrapper (int DIM[], double *A, double *x, double *b) {
foo(DIM[0], DIM[1], A, x, b);
}
class TheClass {
private:
ftype m_function;
void my_function (int DIM[], double *A, double *x, double *b) {
// Change something before performing MV mult.
m_function(DIM, A, x, b);
}
public:
void set_function (ftype p) { m_function = p; }
void call_function() {
int DIM[2] = {2,2};
if (m_function) m_function(DIM, 0, 0, 0);
}
void call_nasty_function() {
TheClass nasty_class;
ftype f = tr1::bind(&TheClass::my_function, this, _1, _2, _3, _4);
nasty_class.set_function(f);
nasty_class.call_function();
}
};
int main () {
TheClass one_class;
one_class.set_function(foo_wrapper);
one_class.call_function();
one_class.call_nasty_function();
}
PS. Creating a std::function with more than 10 variables seemed possible (compiled, but I didn't test) with
#define BOOST_FUNCTION_NUM_ARGS 15
#include <boost/function/detail/maybe_include.hpp>
#undef BOOST_FUNCTION_NUM_ARGS
But creating a std::bind for more than 10 arguments does not seem as easy.
std::function, std::bind, and lambdas are what you are looking for. In short, function pointers are very bad things and should be burned in fire. In long, std::function can store any function object which can be called with the correct signature, and you can use std::bind or a lambda to generate a function object that calls your member function quickly and easily.
Edit: Then you will just have to roll your own std::function equivalent that supports more than 10 arguments.
I would like to use GSL within a c++ class without declaring member functions as static. The reason for this is because I don't know them too well and I'm not sure about thread safety. From what I read, std::function might be a solution but I'm not sure how to use it.
My question comes down to how can I remove static in declaration of g?
#include<iostream>
#include <functional>
#include <stdlib.h>
#include <gsl/gsl_math.h>
#include <gsl/gsl_monte.h>
#include <gsl/gsl_monte_plain.h>
#include <gsl/gsl_monte_miser.h>
#include <gsl/gsl_monte_vegas.h>
using namespace std;
class A {
public:
static double g (double *k, size_t dim, void *params)
{
double A = 1.0 / (M_PI * M_PI * M_PI);
return A / (1.0 - cos (k[0]) * cos (k[1]) * cos (k[2]));
}
double result() {
double res, err;
double xl[3] = { 0, 0, 0 };
double xu[3] = { M_PI, M_PI, M_PI };
const gsl_rng_type *T;
gsl_rng *r;
////// the following 3 lines didn't work ///////
//function<double(A,double*, size_t, void*)> fg;
//fg = &A::g;
//gsl_monte_function G = { &fg, 3, 0 };
gsl_monte_function G = { &g, 3, 0 };
size_t calls = 500000;
gsl_rng_env_setup ();
T = gsl_rng_default;
r = gsl_rng_alloc (T);
{
gsl_monte_plain_state *s = gsl_monte_plain_alloc (3);
gsl_monte_plain_integrate (&G, xl, xu, 3, calls, r, s, &res, &err);
gsl_monte_plain_free (s);
}
gsl_rng_free (r);
return res;
}
};
main() {
A a;
cout <<"gsl mc result is " << a.result() <<"\n";
}
Update (1):
I tried changing gsl_monte_function G = { &g, 3, 0 }; to gsl_monte_function G = { bind(&A::g, this,_1,_2,_3), 3, 0 }; but it didn't work
Update (2):
I tried using assigning std::function to a member function but it didn't work either.
Update (3)
in the end I wrote a non-member function:
double gmf (double *k, size_t dim, void *params) {
auto *mf = static_cast<A*>(params);
return abs(mf->g(k,dim,params));
//return 1.0;
};
It worked but it's a messy solution because I needed to write a helper function. With lambdas,function and bind, there should be a way to have everything logical within the class.
You can easily wrap member functions using the following code (which is a well known solution)
class gsl_function_pp : public gsl_function
{
public:
gsl_function_pp(std::function<double(double)> const& func) : _func(func){
function=&gsl_function_pp::invoke;
params=this;
}
private:
std::function<double(double)> _func;
static double invoke(double x, void *params) {
return static_cast<gsl_function_pp*>(params)->_func(x);
}
};
Then you can use std::bind to wrap the member function in a std::function. Example:
gsl_function_pp Fp( std::bind(&Class::member_function, &(*this), std::placeholders::_1) );
gsl_function *F = static_cast<gsl_function*>(&Fp);
However, you should be aware about the performance penalties of std::function before wrapping member functions inside gsl integration routine. See template vs std::function . To avoid this performance hit (which may or may not be critical for you), you should use templates as shown below
template< typename F >
class gsl_function_pp : public gsl_function {
public:
gsl_function_pp(const F& func) : _func(func) {
function = &gsl_function_pp::invoke;
params=this;
}
private:
const F& _func;
static double invoke(double x, void *params) {
return static_cast<gsl_function_pp*>(params)->_func(x);
}
};
In this case, to call a member function you need the following
Class* ptr2 = this;
auto ptr = [=](double x)->double{return ptr2->foo(x);};
gsl_function_pp<decltype(ptr)> Fp(ptr);
gsl_function *F = static_cast<gsl_function*>(&Fp);
PS: the link template vs std::function explains that compiler usually has an easier time optimizing templates than std::function (which is critical for performance if your code is doing heavy numerical calculation). So even tough the workaround in the second example seems more cumbersome, I would prefer templates than std::function.
GSL takes a C-type functions “int (*)(char,float)” rather than C++-type “int (Fred::*)(char,float)”. To convert a member function to the C-type function, you need to add static.
see Is the type of “pointer-to-member-function” different from “pointer-to-function”?
Why are you worried about the static function in this case?
Variables and/or objects declared in a static function are not shared between different threads unless they are static themselves (which in your case they are not).
Is your code failing to do something?
Sorry, but what you're trying to do doesn't make any sense. Whatever thread safety issues you're worried about, they won't be solved by adding or removing the static keyword.
The only reason why you would make g non-static would be if an instance of A was somehow required for g's operation. And g's current implementation doesn't require such an instance.
Note you can also make g a global function, without the static keyword. There would be no visible difference in your case. However it's better style in your case to have g in the class which makes use of it, as a static function.
Also, Here is some related material about pointers to (static/non-static) member functions.
EDIT: MOTIVATION
Suppose I define a Handler class as
class Handler {
public:
class Message { /*...*/ };
typedef int (*Callback)(Message *msg);
void registerCallback(int msgclass, Callback f);
};
A client can do
int f1(Handler::Message *msg)
{ /* handle message */ }
int f2(Handler::Message *msg)
{ /* handle message */ }
int main(){
Handler h;
h.registerCallback(1, f1);
h.registerCallback(2, f2);
// ....
}
The compiler will indeed check that f1 and f2 are appropriate as parameters to registerCallback, however, it's up to the client to define f1 and f2 correctly. Since I've allready typedefed Callback, I'd like the client to be able to use it instead.
END EDIT
I'd like to do something like this:
typedef int arithmetic(int i, int j);
arithmetic sum
{
return i+j;
}
arithmetic max
{
return (i>j)? i:j;
}
// etc.
However, both
arithmetic sum
arithmetic sum()
don't compile, and also this
arithmetic sum(int i, int j)
which gives compiler error of
func.cpp:4: error: ‘sum’ declared as
function returning a function
The reason I want this is that I want to have a Handler class which would provide a typedef for a callback function it accepts, including the parameter list.
I'll give you a classic C answer, without resorting to the newfangled C++0x toys. Let's start by defining a function prototype:
typedef int TWO_ARG_FUNC(int x, int y);
You can use this prototype when receiving a function pointer, e.g.:
void blah(TWO_ARG_FUNC* funcPtr);
... or when forward-declaring a function:
TWO_ARG_FUNC max;
... but you cannot implement a function by just writing the prototype, e.g.:
TWO_ARG_FUNC max
{
... // bzzt, error!
}
However, not all is lost. You can enforce the function to remain true to a prototype by first forward-declaring it:
TWO_ARG_FUNC max;
int max(int a, int b)
{
...
}
Another option would be to resort to C macros:
#define DEFINE_TWO_ARG_FUNC(funcName) int funcName(int a, int b)
DEFINE_TWO_ARG_FUNC(max)
{
}
and you can even use the macro to declare a function prototype, in case you later want to declare a pointer to such a function:
typedef DEFINE_TWO_ARG_FUNC(TWO_ARG_FUNC);
First, you did not typedef a signature. A signature is everything that identifies a single function. It contains the namespace/class of the function and so on.
What you typedef'ed is the type of a function. Like when you typedef int inttype which typedefs the type of an int, you typedef'ed the type of a function.
You can use the typedef-name to declare functions only.
arithmetic max; // valid
But it cannot be used to define functions. For defining functions, you need to provide a parameter list literally and manually. Reasons include giving names for parameters (and possibly other, more technical reasons. C++0x introduces arithmetic max {}; which will get a specific initialization meaning).
Thinking about your post I will give it a shot about what you want to archive.
You could try using boost or C++0x lambda. I will go with boost.
typedef boost::function<int(int,int)> arithmetic;
arithmetic sum = (boost::lambda::_1 + boost::lambda::_2);
arithmetic max = boost::lambda::if_then_else_return(boost::lambda::_1 > boost::lambda::_2,
boost::lambda::_1, boost::lambda::_2);
int j = sum(3,3); // j ist 6
int k = max(4,2); // k is 4
So maybe this is what you want to archive.
It is also possible with a full blown function.
Here you go.
int FullBodyFunction(int i, int j)
{
return i+j;
}
arithmetic sum2 = boost::bind(&FullBodyFunction, _1, _2);
This will do the same as sum1. You are free to use the whole boost bind stuff. E.g. bind to method of a object or what ever you want.
Since, as you say, you can use C++0x, you might choose to do something like this by typedef'ing a function:
edit, added in your concept of a handler class containing a callback typedef:
#include <functional>
#include <list>
int max(int a, int b)
{
return (a>=b) ? a : b;
}
class Handler
{
public:
//typedef int (*Callback)(int, int);
typedef std::function<int (int, int)> Callback;
void add(Callback func) { functions_.push_back(func); }
private:
std::list<Callback> functions_;
};
int main(int argc, char* argv[])
{
Handler handler;
handler.add([](int a, int b) -> int { return (a>=b) ? a : b; });
handler.add(max);
return 0;
}
This isn't the exact syntax you're looking for, but as others have pointed out, it isn't possible to use typedef for a function signature directly.
I haven't find solution with exact syntax you are looking for, but something like this works:
#include <cassert>
#define arithmetic (int i, int j) -> int
#define declare(Func, Name) auto Name Func
#define as_
auto sum as_ arithmetic
{
return i + j;
};
declare(arithmetic, max)
{
return (i>j) ? i : j;
};
int main()
{
assert(sum(2, 4) == 6);
assert(max(2, 4) == 4);
return 0;
}