提问人:Antonio 提问时间:9/6/2023 最后编辑:Ted LyngmoAntonio 更新时间:9/6/2023 访问量:83
绑定纯虚法
Bind pure virtual method
问:
假设我们有以下层次结构:
class Add3Interface {
virtual int add3 (const int&) const = 0;
};
class Add3: public Add3Interface {
virtual int add3 (const int& arg) const override {
return arg + 3;
}
};
我想绑定该方法,以便我可以在类似的事情中使用它。
以下代码很好:add3
std::views::transform
const Add3 myAdder{};
const auto myFun = std::bind(&Add3::add3, myAdder, std::placeholder::_1);
但是,在我的用例中,我无法访问具体类型,因此我必须编写如下内容:
auto foo(Add3Interface& myAdder) {
const auto myFun = std::bind(&Add3Interface::add3, myAdder,
std::placeholders::_1);
// ...
}
但是,这会使编译器感到不安:
/usr/include/c++/11/tuple:238:13: error: cannot declare field ‘std::_Head_base<0, Add3Interface, false>::_M_head_impl’ to be of abstract type ‘Add3Interface’
如何绑定对象的方法?
我希望类似的东西可能会有所帮助:typeid
const auto myFun = std::bind(&(typeid(myAdder)::add3), myAdder, std::placeholders::_1);
但这只会导致各种语法错误,这些错误取决于我如何放置各种括号。
当然,我们可以只使用lambda:
const auto myFun = [&myAdder] (const auto& arg) { return myAdder.add3(arg); };
但如果可能的话,我更愿意使用,因为我觉得它代表了我从语义角度试图做得更好的地方。bind
答:
std::bind
尝试按值存储其所有参数。在本例中,它尝试复制到 类型的数据成员中。当然,抽象地说,这是失败的。问题不在于成员函数指针的类型错误。myAdder
Add3Interface
Add3Interface
如果要通过引用引用存储的参数,请传递 .您可以使用便利函数或构造 s。std::bind
std::reference_wrapper<T>
T
std::ref
std::cref
std::reference_wrapper
auto foo(Add3Interface& myAdder) {
const auto myFun = std::bind(&Add3Interface::add3, std::ref(myAdder),
std::placeholders::_1);
// ...
}
(准确地说,它本身根本没有专门处理。它只会将 的副本存储为数据成员,就像它存储任何其他参数的副本一样。在函数调用时会正确解包,因为许多标准实用程序用于调用可调用对象的标准 INVOKE
操作会解包它。std::bind
std::reference_wrapper
std::reference_wrapper
std::reference_wrapper
但是,在我的用例中,我无法访问具体类型,因此我必须编写这样的东西
如果要传递 的任何实例,可以定义调用成员函数的静态成员函数:Add3Interface
#include <functional>
#include <iostream>
struct Add3Interface {
virtual int add3 (const int&) const = 0;
static int staticAdd3 (Add3Interface const& ths, const int& arg) { return ths.add3(arg); }
};
struct Add3: Add3Interface {
virtual int add3 (const int& arg) const override {
return arg + 3;
}
};
struct Add4: Add3Interface {
virtual int add3 (const int& arg) const override {
return arg + 4;
}
};
int main()
{
auto myFun = std::bind(Add3Interface::staticAdd3, std::placeholders::_1, std::placeholders::_2);
Add4 add4;
Add3 add3;
std::cout << myFun(add3, 1) << "\n";
std::cout << myFun(add4, 1) << "\n";
}
下一个:具有便捷方法的 C++ 接口
评论
, myAdder,
=>, std::ref(myAdder),
Add3Interface
std::bind
std::auto_ptr