编辑:动机
假设我将Handler类定义为
class Handler {
public:
class Message { /*...*/ };
typedef int (*Callback)(Message *msg);
void registerCallback(int msgclass, Callback f);
};
客户可以
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);
// ....
}
编译器确实会检查f1
和f2
是否适合作为registerCallback
的参数,但是,由客户端定义f1
和{{1}正确的。由于我已经f2
编辑typedef
,我希望客户能够使用它。
结束编辑
我想做这样的事情:
Callback
然而,两者
typedef int arithmetic(int i, int j);
arithmetic sum
{
return i+j;
}
arithmetic max
{
return (i>j)? i:j;
}
// etc.
不编译,也是这个
arithmetic sum
arithmetic sum()
,它给出了
的编译错误func.cpp:4:错误:'sum'声明为 函数返回函数
我想要这个的原因是我希望有一个arithmetic sum(int i, int j)
类,它为它接受的回调函数提供Handler
,包括参数列表。< / p>
答案 0 :(得分:12)
我会给你一个经典的C答案,而不是诉诸于新奇的C ++ 0x玩具。让我们从定义函数原型开始:
typedef int TWO_ARG_FUNC(int x, int y);
接收函数指针时可以使用此原型,例如:
void blah(TWO_ARG_FUNC* funcPtr);
...或正向声明函数时:
TWO_ARG_FUNC max;
...但是你不能只通过编写原型来实现一个函数,例如:
TWO_ARG_FUNC max
{
... // bzzt, error!
}
然而,并非所有人都失去了。您可以通过首先向前声明它来强制执行该功能以保持原型:
TWO_ARG_FUNC max;
int max(int a, int b)
{
...
}
另一种选择是诉诸C宏:
#define DEFINE_TWO_ARG_FUNC(funcName) int funcName(int a, int b)
DEFINE_TWO_ARG_FUNC(max)
{
}
你甚至可以使用宏来声明一个函数原型,以防你以后想要声明一个指向这样一个函数的指针:
typedef DEFINE_TWO_ARG_FUNC(TWO_ARG_FUNC);
答案 1 :(得分:9)
首先,你没有输入一个签名。签名是标识单个功能的所有内容。它包含函数的名称空间/类等。
你输入的内容是函数的类型。就像你typedef int inttype
类型定义int
的类型一样,你输入定义函数的类型。
您可以使用typedef-name仅声明函数。
arithmetic max; // valid
但它不能用于定义函数。要定义函数,您需要按字面和手动提供参数列表。原因包括给出参数的名称(以及可能的其他更多技术原因.C ++ 0x引入arithmetic max {};
将获得特定的初始化含义)。
答案 2 :(得分:3)
考虑一下你的帖子我会试一下你想要存档的内容。 您可以尝试使用boost或C ++ 0x lambda。我会继续提升。
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
所以也许这就是你要存档的内容。
也可以使用完整的功能。 你走了。
int FullBodyFunction(int i, int j)
{
return i+j;
}
arithmetic sum2 = boost::bind(&FullBodyFunction, _1, _2);
这与sum1相同。你可以自由使用整个boost绑定的东西。例如。绑定到对象的方法或任何你想要的东西。
答案 3 :(得分:2)
因为正如你所说,你可以使用C ++ 0x,你可以选择通过typedef'ing function
来做类似的事情:
编辑,添加到包含回调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;
}
这不是您正在寻找的确切语法,但正如其他人所指出的那样,不能直接将typedef用于函数签名。
答案 4 :(得分:2)
我找不到您正在寻找的确切语法的解决方案,但这样的方法有效:
#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;
}