在 C# 中我可以这样做:
delegate void myFunctionDelegate<T>(T arg);
在 C++ 中,我明白我需要为函数指针的模板使用别名,但语法太奇怪了,我发现的所有示例都让我更加困惑。
以下是错误的;我该如何纠正它?
template<typename T>
using myFunctionDelegate = void (*)(T arg);
我想这样使用它:
template<class T> class Foo
{
...
void someOtherFunction(myFunctionDelegate callback)
{
...
callback(someValue);
}
}
然后:
myClassInstance.someOtherFunction([&](T arg) {
// do something with the callback argument
});
最佳答案
您所拥有的几乎可以在句法上起作用; myFunctionDelegate
的使用只需要一个类型参数:
void someOtherFunction(myFunctionDelegate<T> callback)
^^^
如果您没有从中获得任何特别的好处,别名参数名称是可选的:
template<typename T>
using myFunctionDelegate = void(*)(T);
但是,还有一个更大的问题:函数指针不处理状态。示例调用中使用的 lambda 通过捕获它来使用状态。因此,捕获的 lambda 不能转换为函数指针。当传入这样一个 lambda 非常方便时,函数参数应该支持它。
有两种常用的方法。首先是忘记强制特定的返回和参数类型。相反,让调用者传递任何可以按照函数调用方式调用的对象(lambda、函数指针、仿函数、std::bind
的结果):
template<typename Callable>
void someOtherFunction(Callable callback) {
...
callback(someValue);
}
如果调用不起作用,代码将无法编译1(不幸的是,错误不是很有帮助,但 future 的Concepts 补充可以很容易地帮助那里)。
另一方面,您可能希望明确指定函数类型。 C++ 有一个通用类型来存储任何可调用对象(参见上面的列表)。该类型是 std::function
。它比简单的模板参数更重量级,但在您需要时很有用。
template<typename T>
using myFunctionDelegate = std::function<void(T)>;
void someOtherFunction(const myFunctionDelegate<T> &callback) {...}
[1]:这并不总是正确的(参见 SFINAE),但就您而言可能是正确的。
关于c# - C# 通用委托(delegate)的 C++ 等效语法,以及与 lambda 的用法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28890918/