1
#include <functional>

void foo(std::function<void()> f) { f(); }
void foo(void (*f)()) { f(); }

int main ()
{
  foo( [](){} );
}

VS 编译、gcc 和 clang 抱怨重载模棱两可。谁是对的?lambda 应该是类类型,所以它和函数指针之间不应该有任何转换。因此,VS 似乎是正确的,不顾一切。但也许我错过了一些东西。

除了将 lambda 转换为任一类型之外,是否有一种简单的方法来消除调用歧义?

4

2 回答 2

4

lambda 创建一个可以调用的匿名且未指定的对象,它既不是函数指针也不是std::function对象,但可以用作函数指针和std::function对象,给您带来模棱两可的重载错误。我会说VS是错误的。

此外,由于函数指针可用于创建std::function对象,我想说如果您已经有一个带参数的函数,则不需要使用带函数指针的重载std::function

于 2013-07-21T11:14:13.563 回答
3

非捕获 lambda 具有到具有相同签名的函数指针的隐式转换。这在第 5.1.2 章第 6 段中有规定:

没有 lambda-capture 的 lambda 表达式的闭包类型具有一个公共的非虚拟非显式 const 转换函数,该函数指向具有与闭包类型的函数调用运算符相同的参数和返回类型的函数的指针。这个转换函数返回的值应该是一个函数的地址,当被调用时,它与调用闭包类型的函数调用运算符具有相同的效果。

于 2013-07-21T13:27:21.807 回答