我有一个函数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
答案 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;结合