如何替换"模板<类型名称..."用宏?

How to replace "template <typename ..." with a macro?

本文关键字:类型 用宏 lt 模板 何替换 替换      更新时间:2023-10-16

用什么宏可以用更短的东西代替"template…"样板文件?例如:

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) { ... }

我不建议您仅仅为了避免使用一些标记而使用MACRO。因为类模板的成员定义必须在同一个文件中,所以你必须在同一个文件中定义它们,即使你在类之外这样做。

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

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

好吧,如果你可以美化你的模板样板:

#define pretty ugly

只要你觉得没有伤害。

对于类型,您总是可以使用typedef

如果你真的不喜欢打字,你可以用class代替typename,为你的应用程序域使用标准化的模板名,用struct代替class以避免输入public:,最后使类头只:

template <class N, class A>
struct GraphDirected
{
    GraphDirected() {} // default constructor
    // rest of the class definition
private:
    // helpers and data go here
};

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将向任何试图维护它的人解释代码。但是,需要注意的是,这可能很快导致代码不可读和不可维护。一个更好的解决方案是使用一个编辑器,它既可以帮你完成这些,又可以把它们折叠起来,这样你就看不到它们了。这样,实际的文件将以更标准的格式保存,以便下次编辑时使用(无论是您还是其他人)。