typedef'ing function *signature* (not a pointer to), so that it can be reused?

人盡茶涼 提交于 2019-12-04 05:39:27

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).

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

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;
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!