c++ - 创建函数变量 vector 时出现 "No matching function for call"错误

标签 c++ c++17 variant

我正在尝试创建一个 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/

相关文章:

c++ - 使用迭代器打印出集合的每个成员

c++ - sobel 过滤算法 (C++)(无库)

c++ - C++ 中的链 optional

c - 调用采用非常量指针参数、const_cast、reinterpret_cast、launder 的 c 函数的正确方法

c++ - 有没有希望有效地调用 std::variant 上的公共(public)基类方法?

C++ MPI 标准 3

c++ - 如何在QPalette中使用QPROPERTY?

c++ - 从 std::string_view 派生的对象的比较在 MSVC 中不明确

c++ - 如何初始化这个具有两个类似替代方案的 std::variant 数据成员?

c++ - 使用 lambda 和定点组合器递归访问 `std::variant`