我具有以下类结构(我的实际实现的简化示例):
/* TestClass.hpp */
#pragma once
template <class Impl>
class CurRecTemplate {
protected:
CurRecTemplate() {}
~CurRecTemplate() {}
Impl& impl() { return static_cast<Impl&>(*this); }
const Impl& impl() const { return static_cast<const Impl&>(*this); }
};
template <class Impl>
class BaseClass : public CurRecTemplate<Impl> {
public:
BaseClass() { };
template <class FuncType>
double eval(const FuncType& func, double x) const
{
return this->impl().evalImplementation(func, x);
}
};
class DerivedClass : public BaseClass<DerivedClass> {
public:
template <class FuncType>
double evalImplementation(const FuncType& f, double x) const
{
return f(x);
};
};
然后
/* Source.cpp */
#include <pybind11/pybind11.h>
#include "TestClass.hpp"
namespace py = pybind11;
template<typename Impl>
void declare(py::module &m, const std::string& className) {
using DeclareClass = BaseClass<Impl>;
py::class_<DeclareClass, std::shared_ptr<DeclareClass>>(m, className.c_str())
.def(py::init<>())
.def("eval", &DeclareClass::eval);
}
PYBIND11_MODULE(PyBindTester, m) {
declare<DerivedClass>(m, "DerivedClass");
}
我是根据对这个问题PyBind11 Template Class of Many Types的回答大致得出的。但是我得到的错误是:
C2783'pybind11 :: class_>&pybind11 :: class _> :: def(const char *,Func &&&,const Extra&...)':无法推断出'Func'... \ source的模板参数。 cpp 10
C2672'pybind11 :: class _> :: def':找不到匹配的重载函数... \ source.cpp 12
这似乎与第二个template <class FuncType>
有关,因为通用函数func
将在以后传递,因此我无法在任何地方定义它。有什么办法可以避免这个问题?
答案 0 :(得分:1)
eval
必须是一个接受double并返回double(或可转换为double的类型)的函数,因此您可以使用&DeclareClass::eval<double(*)(double)>
来专门化模板;或者最好包含<functional>
和<pybind11/functional.h>
,您可以完全删除模板,并使eval
以std::function<double(double)>
作为其第一个参数。
更具体地说,我将重写如下
/* TestClass.hpp */
#pragma once
#include <functional>
template <class Impl>
class CurRecTemplate {
protected:
CurRecTemplate() {}
~CurRecTemplate() {}
Impl& impl() { return static_cast<Impl&>(*this); }
const Impl& impl() const { return static_cast<const Impl&>(*this); }
};
template <class Impl>
class BaseClass : public CurRecTemplate<Impl> {
public:
BaseClass() { };
double eval(std::function<double(double)> func, double x) const
{
return this->impl().evalImplementation(func, x);
}
};
class DerivedClass : public BaseClass<DerivedClass> {
public:
double evalImplementation(std::function<double(double)> f, double x) const
{
return f(x);
};
};
/* Source.cpp */
#include <pybind11/pybind11.h>
#include "TestClass.hpp"
#include <pybind11/functional.h>
namespace py = pybind11;
template<typename Impl>
void declare(py::module &m, const std::string& className) {
using DeclareClass = BaseClass<Impl>;
py::class_<DeclareClass, std::shared_ptr<DeclareClass>>(m, className.c_str())
.def(py::init<>())
.def("eval", &DeclareClass::eval);
}
PYBIND11_MODULE(Project1, m) {
declare<DerivedClass>(m, "DerivedClass");
}