C#泛型委托的C ++等效语法以及lambdas的用法

内森·里德利(Nathan Ridley)

在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时,函数参数应该支持它。

有两种常用的方法。首先是忘记强制使用特定的返回值和参数类型。相反,让调用者传递std::bind可以调用函数的方式调用的任何对象(lambda,函数指针,函子,的结果):

template<typename Callable>
void someOtherFunction(Callable callback) {
    ...
    callback(someValue);
}

如果调用不起作用,则代码将无法编译1(不幸的是,该错误不太有用,但将来在Concepts中添加的内容很容易在其中提供帮助)。

另一方面,您可能要显式指定函数类型。C ++具有通用类型来存储任何可调用对象(请参见上面的列表)。该类型是std::function它比简单的模板参数要重一些,但是在需要时很有用。

template<typename T>
using myFunctionDelegate = std::function<void(T)>;

void someOtherFunction(const myFunctionDelegate<T> &callback) {...}

[1]:这并不总是正确的(请参阅SFINAE),但是就您所关心的而言,这可能是正确的。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章