消除对带有std ::函数的函数的调用 [英] Disambiguating calls to functions taking std::functions

查看:175
本文介绍了消除对带有std ::函数的函数的调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面的代码不能在gcc 4.5上编译,因为调用foo是不明确的。消除歧义的正确方法是什么?

  #include< iostream> 
#include< functional>
using namespace std;

void foo(std :: function< void(int,int)> t)
{
t(1,2)
}

void foo(std :: function< void(int)> t)
{
t
}

int main()
{
foo([](int a,int b){cout<<a:< ; a<<b:<< b<< endl;});
}


解决方案

创建一个正确类型的 std :: function 对象,然后将该对象传递给函数:

  std :: function< void(int,int)> func = 
[](int a,int b){cout< a:<< a<< b:<< b<< endl; }
foo(func);

或内联:

  foo(
std :: function< void(int,int)>(
[](int a,int b){cout< ;< a<<b:<< b<< endl;}

std :: function 接受任何内容:

 模板< class F>函数(F); 

因为这个原因,编译器没有办法知道在重载解析过程中 foo 选择: std :: function< void(int)> std :: function< void (int,int)> 有一个构造函数,可以将您的lambda表达式作为参数。



c> std :: function 对象,在重载解析时优先使用 std :: function copy构造函数,

如果捕获列表保证为空,那么,你也可以使用普通的函数指针。在C ++ 0x中,无捕获的lambda可以隐式转换为函数指针。所以,你可以使用类似

  void foo(void(* t)(int,int) 2)。 } 

void foo(void(* t)(int)){t(1); }

并直接调用 foo lambda(或具有匹配类型的函数指针)。



请注意,这种转换是草案语言标准的一个新近的补充(今年二月增加) ,所以它不可能被广泛支持。 Visual C ++ 2010不支持它;我不知道最新的g ++。


The code below doesn't compile on gcc 4.5 because the call to foo is ambiguous. What is the correct way to disambiguate it?

#include <iostream>
#include <functional>
using namespace std;

void foo(std::function<void(int, int)> t)
{
    t(1, 2);
}

void foo(std::function<void(int)> t)
{
    t(2);
}

int main()
{
    foo([](int a, int b){ cout << "a: " << a << " b: " << b << endl;});
}

解决方案

The best way is to explicitly create a std::function object of the correct type then pass that object to the function:

std::function<void(int, int)> func = 
    [](int a, int b) { cout << "a: " << a << " b: " << b << endl; }
foo(func);

or inline:

foo(
    std::function<void(int, int)>(
        [](int a, int b) { cout << "a: " << a << "b: " << b << endl; }
));

std::function has a constructor template that accepts anything:

template<class F> function(F);

Because of this, there's no way for the compiler to know during overload resolution which foo to select: both std::function<void(int)> and std::function<void(int, int)> have a constructor that can take your lambda expression as an argument.

When you pass a std::function object directly, the std::function copy constructor is preferred during overload resolution, so it is selected instead of the constructor template.


Answer for the future: If the capture list is guaranteed to be empty, you can also use ordinary function pointers. In C++0x, a captureless lambda is implicitly convertible to a function pointer. So, you can use something like

void foo(void (*t)(int, int)) { t(1, 2); }

void foo(void (*t)(int)) { t(1); }

and call foo directly with the captureless lambda (or a function pointer with matching type).

Note that this conversion is a very recent addition to the draft language standard (it was added in February of this year), so it is not likely to be widely supported yet. Visual C++ 2010 doesn't support it yet; I don't know about the latest g++.

这篇关于消除对带有std ::函数的函数的调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆