c++ - `overload_cast` 在特定情况下失败

标签 c++ pybind11

我发现了 overload_cast 失败的特定情况,我不知道如何解决这个问题。

显示该行为的最小示例是

#include <pybind11/pybind11.h>

// ----------------

template<class InputIterator, class OutputIterator>
void absolute(
  const InputIterator first, const InputIterator last, const OutputIterator result
)
{
  for ( auto it = first ; it != last ; ++it )
    *it = std::abs(*it);
}

// ----------------

std::vector<double> absolute(const std::vector<double> &in)
{
  std::vector<double> out = in;

  for ( auto &i: out )
    i = std::abs(i);

  return out;
}

// ----------------

namespace py = pybind11;

PYBIND11_MODULE(example,m)
{
  m.def("absolute", py::overload_cast<const std::vector<double>&>(&absolute));
}

编译使用例如:

clang++ -O3 -shared -std=c++14 `python3-config --cflags --ldflags --libs` example.cpp -o example.so -fPIC

给予:

example.cpp:32:21: error: no matching function for call to object of type 'const
      detail::overload_cast_impl<const vector<double, allocator<double> > &>'
  m.def("absolute", py::overload_cast<const std::vector<double>&>(&absolute));
                    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/local/include/pybind11/detail/common.h:727:20: note: candidate template ignored: couldn't infer
      template argument 'Return'
    constexpr auto operator()(Return (*pf)(Args...)) const noexcept
                   ^
/usr/local/include/pybind11/detail/common.h:731:20: note: candidate template ignored: couldn't infer
      template argument 'Return'
    constexpr auto operator()(Return (Class::*pmf)(Args...), std::false_type = {}) const noexcept
                   ^
/usr/local/include/pybind11/detail/common.h:735:20: note: candidate function template not viable:
      requires 2 arguments, but 1 was provided
    constexpr auto operator()(Return (Class::*pmf)(Args...) const, std::true_type) const noexcept
                   ^
1 error generated.

删除第一个函数(我不会重载)或更改其签名可以解决问题。但这显然不是我想要的。

最佳答案

using sig = std::vector<double>(const std::vector<double> &in);

py::overload_cast<const std::vector<double>&>((sig*)&absolute)

与 C++ 中的几乎所有其他内容不同,&absolute 不引用实际值或对象。

相反,它指的是一个重载集;在这种情况下,一个包含特定签名和模板的重载集。

用于推导Return 的模板模式匹配失败。

通过转换为特定的签名,(sig*)&absolute 现在指的是一个对象或值——在本例中,是指向特定函数的指针。现在模板模式匹配可以推断出 Return 的类型。

在 C++ 中,一般规则是可调用对象没有特定的签名。您可以询问使用特定参数调用的可调用对象返回什么,但询问可调用对象希望使用什么参数调用它是一种错误的形式。假设可调用对象是 PMF 或函数指针也是一种错误的形式。

人们总是绕过这个问题,它会导致烦人的错误,就像您的代码所展示的那样。

关于c++ - `overload_cast` 在特定情况下失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49452957/

相关文章:

c++ - 理解指针和内存管理

pybind11,将 std::vector 转换为 py::list

c++ - 从 C++ 中的另一个线程读取指针

python - 简单的 pybind11 模块失败,没有命名模块

python - 如何使用 pybind11 包装模板类

python - pybind11 - 如果访问了结构的任何成员,则 boost::optional 结构的 std::vector 成员将被清空

c++ - 使用 Makefile 中的头文件编译 Pybind(不使用 cmake)

c++ - 仅显示 1 个 opengl 3d 立方体

C++ 显示 char while 循环行

c++ - 2 昏暗数组和双指针