我正在尝试创建一个 std::vector
可以容纳std::function
使用 std::variant
的不同签名的对象.
为什么以下代码无法编译:
#include <functional>
#include <variant>
#include <vector>
int main()
{
std::vector<std::variant<
std::function< int (const std::vector<float>&, int) >,
std::function< float (const std::vector<float>&, int) >
>> func_vector;
func_vector.emplace_back( [] (const std::vector<float>& ret, int index) { return ret.size(); });
return 0;
}
问题发生在
emplace_back()
期间.编译这个会给出一长串错误,列出的第一个是:error: no matching function for call to ‘std::variant<std::function<int(const std::vector<float, std::allocator<float> >&, int)>, std::function<float(const std::vector<float, std::allocator<float> >&, int)> >::variant(main()::<lambda(const std::vector<float>&, int)>)’
{ ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
它说它找不到匹配的函数,但是究竟是什么调用呢?
我试图放置的 lambda 恰好具有我在变体中指定的类型之一的签名,所以一切都应该没问题,不是吗?
最佳答案
emplace_back
应该将 lambda 直接转发到变量初始化。并且有一个转换构造函数可以从任何可转换为成员类型的参数初始化变体的成员。然而,问题是变体的两个成员都可以从此 lambda 初始化,从而产生歧义。
是的,您的 lambda 是 std::function< float (const std::vector<float>&, int) >
的有效初始化程序.这是由于std::function
的方式执行类型删除。它将它持有的可调用结果转换为它指定的返回类型。 callable 只需要能够接受 std::function
的参数列表。 .
为了说明这一点,如果我们向 std::function
之一添加第三个参数类型,
std::vector<std::variant<
std::function< int (const std::vector<float>&, int) >,
std::function< float (const std::vector<float>&, int, int) >
>> func_vector;
然后是 would be no ambiguity . lambda 现在仅是一个变体成员的有效初始值设定项。
解决方法是要么强制转换为您希望保留的确切函数类型,要么告诉放置的变体它应该初始化哪个选项,例如:
func_vector.emplace_back( std::in_place_index<0>, [] (const std::vector<float>& ret, int ) { return ret.size(); });
关于c++ - 创建函数变量 vector 时出现 "No matching function for call"错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59096115/