通过父母投射()
大师和模板专家,我需要你的帮助......
我目前正在寻找解决方案来检查QObject的父层次结构。 我有一个自定义的QDialog具有以下层次结构(父到子):
QDockWidget
> CustomDockArea
> QMainWindow
> QDockWidget
> CustomDialog
在CustomDialog类中,我想检查对话框的层次结构是否与此示例匹配,因此我检查了是否可以用可变参数模板实现,例如:
assert(qobject_cast_parent<QDockWidget*, QMainWindow*, CustomDockArea*, QDockWidget*>(this));
我已经想出了这样的东西:
template <class T, class... Ts>
inline T qobject_cast_parent(QObject* root)
{
if (root)
{
if (sizeof...(Ts) == 0)
{
return qobject_cast<T>(root->parent());
}
else
{
return qobject_cast_parent<Ts...>(root->parent());
}
}
else
{
return nullptr;
}
}
但是,有几个问题:我需要参数包的最后一个参数作为函数的返回类型,在我们的示例QDockWidget *中。 我可以将第一个参数作为返回类型,但这会使模板调用有点麻烦。 但是,即使解决了这个问题,我认为参数包的“展开”方式仍然存在问题,现在我有点不确定我的模板方法对于原始问题是否可行。 也许你可以给我一些提示。 提前致谢!!!
使用c ++ 14,你可以简单地使用auto
作为返回类型:
template <class T>
T* qobject_cast_parent(QObject* root)
{
return root
? qobject_cast<T*>(root->parent())
: nullptr;
}
template <class T, class T2, class... Ts>
auto qobject_cast_parent(QObject* root)
//-> typename Last<T2, Ts...>::type /* In c++11, you have to create this traits */
{
return root
? qobject_cast_parent<T2, Ts...>(qobject_cast<T*>(root->parent()))
: nullptr;
}
由于我没有完整的代码,我只能确认下面的代码是编译的,但是不能测试它。 我相信你可以为我做测试,让我知道如果这不起作用或者我误解了你的问题。
#include <QtCore/QObject>
#include <cassert>
#include <type_traits>
// This ends the recursion with the actual qobject_cast.
template <class T, class U>
inline U *qobject_cast_parent(T* root)
{
// Make sure everything's a QObject, clear message if not.
static_assert(std::is_base_of<QObject, T>::value, "Object must be a QObject");
if (root)
{
return qobject_cast<U *>(root->parent());
}
else
{
return nullptr;
}
}
template <class T, class U, class... Us>
inline U *qobject_cast_parent(T* root)
{
// Make sure everything's a QObject, clear message if not.
static_assert(std::is_base_of<QObject, T>::value, "Object must be a QObject");
if (root)
{
return qobject_cast_parent<U, Us...>(qobject_cast<U *>(root->parent()))
}
else
{
return nullptr;
}
}
所以模板参数是从小孩到父母排序的,你也将被迫指定最内层的类型。 所以我认为你的assert
示例看起来像这样(再次,未经测试,让我知道它是如何工作的):
assert(qobject_cast_parent<CustomDialog,
QDockWidget,
QMainWindow,
CustomDockArea,
QDockWidget>(this));
编辑 :为了完整起见,您还询问了一种获取参数包的最后一个参数类型的方法。 你可以使用这样的东西:
template <typename T, typename... Ts>
struct Last
{
typedef typename Last<Ts...>::type type;
};
template <typename T>
struct Last<T>
{
typedef T type;
};
int main()
{
// For example, this gives std::string:
Last<int, float, char, std::string>::type foo = "bar";
return 0;
}
链接地址: http://www.djcxy.com/p/66893.html
上一篇: cast via parent()