我有两个函数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; }
将< code>int()与< code>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以来]
此构造函数不参与重载解析,除非f对于参数类型Args是可调用的...和返回类型R
问题存在于如何允许调用绑定。正如cppreference所说
如果调用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
考虑以下示例:
假设我们有以下简单的代码: 这段代码使用clang编译并打印“T”,但使用gcc我们有以下错误: 我的问题是哪个编译器有bug,gcc还是叮当声?
请考虑以下人为的代码段: 如果第二个重载被更改为采用至少2种类型的包而不是至少一种类型的包时,gcc和clang都接受这两个调用: 如果未推导出的模板参数被移动到推导出的模板参数,则: 我希望每个版本的所有调用都可以。上面代码示例的预期结果是什么?
问题内容: 使用Java 8,我得到以下代码的编译器错误: 因此,基本上,编译器会说“我知道您会返回,但您不应该返回,如果不知道,我不确定使用哪种方法”,而不是“哦,您将返回,您必须指代该方法的版本” ?如何产生这种混乱? 我知道(如果它们有一个通用的Type),但事实并非如此。 我确实知道如何解决它;如果我这样做很好 但我很好奇是什么原因造成的。 问题答案: 为了清楚起见,可以对此进行一些简化:
我在尝试用std::function和std::bind绑定方法时遇到了一个问题。 在我的通信服务类中: CommunicationService::ManageGetRequest签名: BindGET签名: 请求函数类型定义: BindGET上的错误: 错误C2664:“void RESTServer::BindGET(RequestFunction)”:无法从“std::\u Binder”
在下面的代码中,对< code>foo的第一次调用不明确,因此无法编译。 第二个在lambda前面添加了< code> ,解析为函数指针重载。 符号在这里做什么?