使用可调用参数重载可调用对象

Posted

技术标签:

【中文标题】使用可调用参数重载可调用对象【英文标题】:Overloading on callable with callable parameter 【发布时间】:2013-01-27 07:04:41 【问题描述】:

我正在尝试将如下 C# 代码翻译成 C++:

void SomeCall(Action action)

   // do things like action();  



void SomeCall(Action<Action> action)

   // define some action1   
   // do things like action(action1);   


SomeCall 的 C++ 等效项应该能够采用 std::function 以及具有相同签名的内联和轮廓 C++ lambda。

在浏览了许多关于 C++ std::function 和 lambdas 重载的 SO 问题之后,似乎 答案应该是这样的:

template<typename Func>
enable_if<Func is something callable>
void SomeCall(Func&& action)

 ...


template<typename Func>
enable_if<Func is something callable taking another callable as the parameter>
void SomeCall(Func&& action)

 ...


你能帮我填空吗?

【问题讨论】:

R.Martinho Fernandes 写了一个比我好得多的解决方案,但他 cba 写了一个答案。这是他的:liveworkspace.org/code/1b7ka6$1 @Seth Visual Studio 2012 Update 1 编译器不喜欢它并弹出错误 C2995: ''unknown-type' f(T &&)' : function template has been defined 消息为第二个模板功能。 “TMP”是什么意思? @phresnel 模板元编程 【参考方案1】:

您可以尝试像这样使用标准重载:

void Fn( std::function<int(int)>& fn )



void Fn( std::function<int(float)>& fn )


如果这是不可接受的,您将不得不对模板元编程进行大量研究,以使 enable_if 以您想要的方式工作,这是可以想象的最虐待狂的编程形式。不过说真的,您可以尝试从 Andrei Alexandrescu 的 Modern C++ Design 开始。

【讨论】:

嗯,Martinho 的代码适用于除 Visual C++ 之外的所有编译器。我向微软提交了一份错误报告,但考虑到他们拥有的其他优先事项,他们说不会很快修复。他的代码实际上很简单,但 MSVC++ decltype 不完整且有缺陷,不仅在这方面。

以上是关于使用可调用参数重载可调用对象的主要内容,如果未能解决你的问题,请参考以下文章

C++可调用对象学习笔记

查明 C++ 对象是不是可调用

C/C++: C++可调用对象详解

lambda表达式

[C++11]可调用对象绑定器

使用迭代器的可调用对象的名称? [关闭]