0

用什么宏可以用更短的东西替换“模板...”样板?即:而不是这些:

template <typename NodeDataT, typename ArcDataT>
/*constructor*/ GraphDirected::
GraphDirected()
{
}
template <typename NodeDataT, typename ArcDataT>
/*destructor*/ GraphDirected::
~GraphDirected()
{
    clear();
}    
template <typename NodeDataT, typename ArcDataT>
void GraphDirected::
clear()
{
    nodes.clear();
    arcs.clear();
}

我想写这个:

boilerplate(/*constructor*/)
GraphDirected()
{
}
boilerplate(/*destructor*/)
~GraphDirected()
{
    clear();
}
boilerplate(void)
clear()
{
    nodes.clear();
    arcs.clear();
}

当然最后我需要一些保护(?#undef?),这样其他文件就不会被弄乱。

如果它不是更复杂,如何处理这样的丑陋?:

template <typename ElemType>
typename BST<ElemType>::nodeT * BST<ElemType>::
recFindNode(nodeT *t, ElemType & key) { ... }

根据屏幕尺寸在android中强制纵向或横向模式

在过去的几个小时里,我一直在做一些研究,以及一些试验和错误,但是我无法为这个问题找到一个完全有效的解决方案。我只想强制我的 android 应用程序保持纵向模式,除非屏幕尺寸足够大(平板电脑),这将迫使应用程序处于横向模式。

到目前为止我已经尝试过:

<activity android:screenOrientation="portrait" android:configChanges="orientation|keyboardHidden">

也:

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);

在我的 onCreate 和 onResume 中。

第一个示例确实有效,但是如果它是平板电脑,这将不允许我检查屏幕尺寸和强制横向模式。此外,如果我在执行异步任务时将手机保持在横向模式,则应用程序将在任务完成后进入横向模式,然后只要我留在屏幕上,我就可以再次在纵向和横向之间切换相同的活动。

所以,我不确定处理这个问题的正确方法是什么?如果我使用第二个示例(其中包含更多代码允许我检查屏幕大小,然后根据大小选择布局)只要我在活动中就可以工作。但是,如果我在开始活动时将手机保持在横向模式,那么一切都会崩溃(所以看起来代码一开始就无效)。

任何可能完全没有任何“错误”的建议,现在就是这种情况,我们将不胜感激!

4

4 回答 4

3

我不建议您使用 MACRO 来避免使用少量令牌。由于类模板成员的定义必须在同一个文件中,因此您必须在同一个文件中定义它们,即使您在类之外执行此操作。

更好的解决方案是在类本身内部定义成员,这样就不必每次定义成员时都重复标记。

请记住,模板会生成丑陋的错误消息,而 MACRO 是邪恶的。如果将两者结合起来,当出现问题时,您会看到更丑陋和疯狂的错误消息。

于 2013-01-08T17:53:38.580 回答
0

好吧,如果您可以通过以下方式美化您的模板样板,我认为没有错:

#define pretty ugly

只要你觉得没有害处。

对于类型,你总是可以做一个 typedef

于 2013-01-08T18:27:09.270 回答
0

如果你真的不喜欢打字,你可以用 替换typenameclass为你的应用程序域使用标准化的模板名称,写struct而不是class避免打字public:,最后使类只有标题:

template <class N, class A>
struct GraphDirected
{
    GraphDirected() {} // default constructor
    // rest of the class definition

private:
    // helpers and data go here
};
于 2013-01-08T18:29:07.837 回答
0

C++ 预处理器对其正在处理的代码知之甚少。因此,您需要#define使用您想要使用的术语。

但是,类似:

template <typename NodeDataT, typename ArcDataT>
/*constructor*/ GraphDirected::
GraphDirected()
{
}
template <typename NodeDataT, typename ArcDataT>
/*destructor*/ GraphDirected::
~GraphDirected()
{
    clear();
}    
template <typename NodeDataT, typename ArcDataT>
void GraphDirected::
clear()
{
    nodes.clear();
    arcs.clear();
}

可以很容易地在一些标题中用这个重写:

#define boilerplate(rType) boilerplate_template rType boilerplate_class::

然后在类定义的顶部:

#define boilerplate_class GraphDirected
#define boilerplate_template template <typename NodeDataT, typename ArcDataT>

那么你可以使用:

boilerplate(/*constructor*/)
GraphDirected()
{
}
boilerplate(/*destructor*/)
~GraphDirected()
{
    clear();
}
boilerplate(void)
clear()
{
    nodes.clear();
    arcs.clear();
}

注意:正如其他人所指出的,这是一个坏主意。对于像示例这样的简单情况,#define文件顶部的两个 s 将向任何试图维护它的人解释代码。但是,请注意,这可能会迅速导致无法读取和无法维护的代码。一个更好的解决方案是使用一个编辑器,它既可以为你完成这些,也可以将它们折叠起来,这样你就看不到它们了。这样,实际文件在下次编辑时保持更标准的格式(无论是您还是其他人)。

于 2017-09-22T06:04:51.640 回答