gpt4 book ai didi

c++ - boost::function 类型兼容,是怎么做到的?

转载 作者:行者123 更新时间:2023-11-28 00:40:55 26 4
gpt4 key购买 nike

解释一下:

struct X
{
void foo(int arg) { cout << "X" << arg << endl; }
};

struct Y
{
void bar(int arg) { cout << "Y" << arg << endl; }
};

int main(int argc, char *argv[])
{
X x;
Y y;

mem_fun1_t<void, X, int> f1 = std::mem_fun(&X::foo);
boost::function<void (int)> f11 = std::bind1st(f1, &x);
f11(2);

mem_fun1_t<void, Y, int> f2 = std::mem_fun(&Y::bar);
boost::function<void (int)> f22 = std::bind1st(f2, &y);
f22(2);

f11 = f22; // WOW, THIS IS ALLOWABLE
}

Boost 如何在幕后工作以允许 f11 = f22 行?

似乎不寻常,因为 f11 是一个仿函数,它的 operator(int) 调用 X::foo(int) 和 x 的 this,所以它似乎是特定于 X 的类型,然后当我对 f2/做同样的事情时f22 它特定于 Y,那么 f11 = f22 这行怎么能被允许呢?

我实际上想执行 f11 = f22 行,但我很惊讶地看到这是允许的,并且我试图理解这为什么不是类型不匹配。

我知道,“使用源代码,Luke”,但是 Boost 源代码很难理解/理解其中发生的一切。

对于您的回答,如果您可以显示通过模板化扩展的类,那将会有所帮助。

我认为它可以通过 void* casting 或类似的东西来解决这个问题,但这似乎是一个 hack,并且在 Boost 之下屈服于那个水平。那么怎么办?

顺便说一句,如果你以前没有遇到过这种事情,你至少应该对这种魔法感到惊讶,因为你不能在上面说“x = y”,因为这显然是不允许的,因为它们是不同的类型并且没有 X::operator=(Y&),所以这就是这种惊奇的来源——这是一个聪明的诡计。

最佳答案

所使用的技术称为类型删除。

我将使用一个用 C++11 编写的玩具类进行演示。许多细节并不准确,但一般技术是:

struct nullary_impl {
virtual void invoke() const = 0;
virtual ~nullary_impl() {}
};
typedef std::shared_ptr<nullary_impl> nullary_pimpl;
struct nullary_func {
nullary_pimpl pimpl;
nullary_func() = default;
nullary_func( nullary_func const& ) = default;
template<typename F>
nullary_func( F const& f );
void operator()() const {
pimpl->invoke();
};
};
template<typename T>
struct nullary_impl_impl:nullary_impl {
T t;
virtual void invoke() const override {
t();
}
nullary_impl_impl( T const& t_ ):t(t_) {}
};
template<typename F>
nullary_func::nullary_func( F const& f ):
pimpl( std::make_shared( nullary_impl_impl<F>(f) )
{}

现在在这种情况下,该类不是模板类,但作为模板类并不是重要的部分。

重要的是它有一个模板构造函数。此模板构造函数根据我们构造 nullary_func 的类型创建自定义类型对象,然后存储指向自定义类型对象抽象基的指针。这个抽象基类有一个我们调用的某种virtual 方法。自定义子类型实现该 virtual 方法,并在基础类型上调用 ()

现在,shared_ptr 可能不是 boost 使用的(可能是某种 value_ptr),并且在 function 你有一个 template 类和 template 构造函数,还有很多其他的细节。如果您愿意,可以实现自己的动态调度而不是 virtual 调用。在真正的 C++11 中,我会做完美转发,解决完美转发单参数构造函数的所有问题。

关于c++ - boost::function<void (int)> 类型兼容,是怎么做到的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18928128/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com