Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/128.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ &引用;“调用”没有匹配的函数;创建函数变量向量时出错_C++_C++17_Variant - Fatal编程技术网

C++ &引用;“调用”没有匹配的函数;创建函数变量向量时出错

C++ &引用;“调用”没有匹配的函数;创建函数变量向量时出错,c++,c++17,variant,C++,C++17,Variant,我正在尝试创建一个std::vector,它可以使用std::variant保存不同签名的std::function对象 为什么不编译以下代码: #include <functional> #include <variant> #include <vector> int main() { std::vector<std::variant< std::function< int (const std::vector<fl

我正在尝试创建一个
std::vector
,它可以使用
std::variant
保存不同签名的
std::function
对象

为什么不编译以下代码:

#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;
}
它说它找不到匹配的函数,但具体是为了什么调用


我试图放置的lambda正好具有我在变体中指定的一种类型的签名,所以一切都应该正常,不是吗?

放置_back
应将lambda直接转发到变体初始化。还有一个转换构造函数,它可以从任何可转换为成员类型的参数初始化变量的成员。然而,问题是变量的两个成员都可以从这个lambda初始化,从而产生歧义

是的,您的lambda是
std::function
的有效初始值设定项。这是由于
std::function
执行类型擦除的方式造成的。它将其持有的可调用的结果强制转换为指定的返回类型。可调用函数必须能够接受
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;
std::vector,
std::function
>>func_向量;
然后是那里。lambda现在只是一个变量成员的有效初始值设定项

解决方法是将其转换为您希望保留的确切函数类型,或者告诉安置的变体它应该初始化哪个选项,例如:

func_vector.emplace_back( std::in_place_index<0>, [] (const std::vector<float>& ret, int ) { return ret.size(); });
func_vector.emplace_back(std::in_place_index,[](const std::vector&ret,int){return ret.size();});

std::variant
的转换构造函数的行为类似于重载解析,以确定要构造的类型

如果你有两个函数

void f(std::function< int (const std::vector<float>&, int) >);
void f(sstd::function< float (const std::vector<float>&, int) >);
void f(std::function);
void f(sstd::function);
然后电话

f([] (const std::vector<float>& ret, int index) { return ret.size(); })
f([](const std::vector&ret,int index){return ret.size();})
如果参数可以使用类型
const std::vector&
int
调用,并且返回类型可以隐式转换为
int
float
,则
std::function
的构造函数也会参与重载解析。这些类型不需要完全相同


因此,这两种重载对于您的lambda都是可能的,因为它们都需要一个用户定义的转换(从lambda类型转换为
std::function
),因此重载的解决方案是不明确的。

非常感谢您的回答!如果您已经演示了如何解决这个问题,那就更好了。@Alex一个不需要修改
emplace\u back
的干净解决方案可能是围绕
std::function
编写一个包装类,只有在类型完全匹配的情况下才能启用其构造函数。我现在没时间写出来。
f([] (const std::vector<float>& ret, int index) { return ret.size(); })