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

问题描述 投票:3回答:1

我有一个函数foo的两个重载,它采用不同的std::functions,当与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调用的一个问题。然后我想“也许有一些神奇的事情来处理函数类型和lambdas并且它不处理实际的类”,但它也处理它们。

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

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

c++ overloading c++14 std-function stdbind
1个回答
4
投票

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

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

换句话说,您需要传递至少与底层callable所期望的一样多的参数。

这意味着以下内容有效

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> bind

© www.soinside.com 2019 - 2024. All rights reserved.