使用std :: function参数的不同重载与bind(有时)不一致

时间:2015-07-01 22:45:51

标签: c++ overloading c++14 std-function stdbind

我有一个函数foo的两个重载,它们使用不同的std::function s,当与std::bind的结果一起使用时,会导致后者出现歧义问题。我不明白为什么这是不明确的。

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

void take_int(int) { }
int ret_int() { return 0; }

int()使用bind函数时,我会出现歧义错误

foo(std::bind(ret_int)); // ERROR

出现gcc-5.1错误(与clang类似)

error: call to 'foo' is ambiguous
  foo(std::bind(ret_int));
  ^~~
note: candidate function
void foo(std::function<void(int)>) {}
     ^
note: candidate function
void foo(std::function<int()>) {}

然而,以下所有工作

foo(std::bind(take_int, _1));
foo(take_int);

foo(ret_int);
foo([](){ return ret_int(); });

struct TakeInt {
  void operator()(int) const { }
};

struct RetInt {
  int operator()() const { return 0; }
};

foo(TakeInt{});
foo(RetInt{});

查看std::function构造函数

template< class F > 
function( F f );

对我来说,任何在不同std::function类型上具有多个重载的函数都应该有歧义,这是有道理的,但它只是调用bind的问题。然后我想到了#34;也许有一些神奇的事情来处理函数类型和lambdas而且它并没有处理实际的类,&#34;但它也处理这些。

有关en.cppreference的说明[自c ++ 14]

  

此构造函数不参与重载决策,除非f对于参数类型Args可调用...并返回类型R

1 个答案:

答案 0 :(得分:4)

如何允许调用bind存在问题。作为cppreference states

  

如果调用g()时提供的某些参数与存储在g中的任何占位符不匹配,则会评估并丢弃未使用的参数。

换句话说,你需要传递至少与底层可调用对象一样多的参数。

这意味着以下内容有效

int f();
auto b = std::bind(f);
b(1, 2, 3); // arguments aren't used

所以说

auto b = std::bind(ret_int)
b(1);

工作,丢弃1,因此以下内容有效,过载选择变得模糊

std::function<void(int)> f = std::bind(ret_int);

反之则不然,但是

std::function<int()> f = std::bind(take_int);

因为take_int无法在没有参数的情况下调用。

外卖:lambda&gt;结合