- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
解释一下:
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/
我是一名优秀的程序员,十分优秀!