问题描述
我有两个函数foo
的重载,它们具有不同的std::function
,当与std::bind
的结果一起使用时,会导致后者的歧义问题.我不明白为什么 only 这是模棱两可的.
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
类型上具有多个重载的任何函数都应具有歧义性,但这只是绑定调用的问题.然后我想:也许在处理函数类型和lambda时发生了一些不可思议的事情,它并没有处理实际的类,"但是它也可以处理那些.
en.cppreference上有一条注释,内容为[c ++ 14起]
问题是如何允许绑定被调用.作为 cpp引用状态
换句话说,您至少需要传递 尽可能多的基础可调用对象期望的参数.
这意味着以下内容有效
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>绑定
I have two overloads of a function foo
which take different std::function
s which results in an ambiguity issue for the latter when used with the result of a std::bind
. I don't understand why only this is ambiguous.
void foo(std::function<void(int)>) {}
void foo(std::function<int()>) {}
void take_int(int) { }
int ret_int() { return 0; }
When using int()
with a bind
function I get an ambiguity error
foo(std::bind(ret_int)); // ERROR
With the gcc-5.1 error (and similar with 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()>) {}
However all of the following work
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{});
Looking at the std::function
constructor
template< class F >
function( F f );
it would make sense to me that any function with multiple overloads on different std::function
types should have ambiguities, but it's only an issue with the call to bind. I then thought "maybe there's some magic happening to handle function types and lambdas and it doesn't deal with actual classes," but it handles those too.
There's a note on en.cppreference that says [since c++14]
The problem exists in how bind is allowed to be called. As cppreference states
In other words, you need to pass at least as many arguments as the underlying callable expects.
This means that the following is valid
int f();
auto b = std::bind(f);
b(1, 2, 3); // arguments aren't used
So saying
auto b = std::bind(ret_int)
b(1);
Works, with the 1
discarded, therefore the following is valid, and overload selection becomes ambiguous
std::function<void(int)> f = std::bind(ret_int);
The inverse is not true, however
std::function<int()> f = std::bind(take_int);
because take_int
cannot be called with no arguments.
Takeaway: lambda > bind
这篇关于std :: function参数的不同重载与bind是不明确的(有时)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!