`overload_cast` 在特定情况下失败
`overload_cast` fails in a specific case
我发现了 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++ 中,一般规则是可调用对象没有特定的签名。您可以询问使用特定参数 returns 调用的可调用对象是什么,但询问可调用对象要使用什么参数调用它是一种错误的形式。假设可调用对象是 PMF 或函数指针也是一种错误的形式。
人们一直在绕过这个问题,它会导致像您的代码所演示的那样烦人的错误。
我发现了 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++ 中,一般规则是可调用对象没有特定的签名。您可以询问使用特定参数 returns 调用的可调用对象是什么,但询问可调用对象要使用什么参数调用它是一种错误的形式。假设可调用对象是 PMF 或函数指针也是一种错误的形式。
人们一直在绕过这个问题,它会导致像您的代码所演示的那样烦人的错误。