如果您写下这样的内容:QFuture<bool> thread_res = QtConcurrent::run([]() {});
幕后有模板魔法,问题是它是有效的c ++代码。
1)template <typename T> class QFutureInterface
有方法
QtPrivate::ResultStore<T> &resultStore()
{ return static_cast<QtPrivate::ResultStore<T> &>(resultStoreBase()); }
(以上为link to Qt sources以上方法。)
2)resultStoreBase
返回ResultStoreBase&
这样的hieracity template <typename T> class ResultStore : public ResultStoreBase
和ResultStoreBase&
确实引用了ResultStoreBase对象, NOT QtPrivate::ResultStore<T>
换句话说,我们有这样的事情:
#include <map>
class Base {
public:
virtual ~Base() {}
protected:
std::map<int, std::string> results_;
};
template <typename T>
class Derived : public Base {
public:
void clear() {
results_.clear();
}
};
struct Foo {
Base base;
template <typename T>
Derived<T> &f() {
return static_cast<Derived<T> &>(base);
}
};
int main()
{
Foo foo;
foo.f<bool>().clear();
}
template<class T> class Derived
没有数据,foo.f<bool>()
只用于调用方法,而不是复制对象或销毁对象,所以唯一可以通过vptr
调用的方法 - 析构函数永远不会通过这样的界面调用。
所以问题是这段代码有未定义的行为吗?
根据这个c++ design: cast from base to derived class with no extra data members这样的代码有任何未定义的行为,但那么为什么Qt的人以这种方式编写它?