C++ 默认模板参数为Null
为什么在模板化函数中不可能使用NULL作为默认指针参数? 让我们编写以下代码:C++ 默认模板参数为Null,c++,templates,c++11,overloading,default,C++,Templates,C++11,Overloading,Default,为什么在模板化函数中不可能使用NULL作为默认指针参数? 让我们编写以下代码: template<class Graph, class NodeAttribs, class ArcAttribs> string graphToGraphviz(Graph &graph, NodeAttribs *nattribs = NULL, ArcAttribs *aattribs = NULL,
template<class Graph, class NodeAttribs, class ArcAttribs> string
graphToGraphviz(Graph &graph,
NodeAttribs *nattribs = NULL,
ArcAttribs *aattribs = NULL,
string name = ""){
/*...*/
}
我有一些怀疑,编译器认为它无法解析NULL的类型,但如果属性为NULL(存在if条件),则不会使用这些类型。但也许编译器无法以正确的方式解决这个问题。如果是,我如何编写这样的重载函数,它将允许我使用缩写形式
我有一个想法,像这样重载它:
class Empty{}
template<class Graph> string
graphToGraphViz(Graph &graph,
string name = ""){
return graphToGraphviz<Graph, Empty, Empty>(graph, NULL, NULL, name)
}
使用C++11语法,函数头将如下所示:
template<class Graph, class NodeAttribs=ListDigraph::NodeMap<string>, class ArcAttribs=ListDigraph::NodeMap<string> > string
graphToGraphviz(Graph &graph,
NodeAttribs *nattribs = NULL,
ArcAttribs *aattribs = NULL,
string name = "")
模板字符串
graphToGraphviz(图形和图形,
NodeAttribs*nattribs=NULL,
ArcAttribs*aattribs=NULL,
字符串名称=”)
但它无法编译,并且会出现大量奇怪的错误。您尝试过吗
template<class Graph, class NodeAttribs, class ArcAttribs> string
graphToGraphviz(Graph &graph,
NodeAttribs *nattribs = (<NodeAttribsClass>*)NULL,
ArcAttribs *aattribs = (<ArcAttribsClass>*)NULL,
string name = ""){
/*...*/
}
模板字符串
graphToGraphviz(图形和图形,
NodeAttribs*nattribs=(*)NULL,
ArcAttribs*aattribs=(*)空,
字符串名称=”){
/*...*/
}
或
模板字符串
graphToGraphviz(图形和图形,
NodeAttribs*nattribs=NULL,
ArcAttribs*aattribs=NULL,
字符串名称=”){
/*...*/
}
其中NodeAttribsClass
和ArcAttribsClass
是可以在该插槽中使用的有效(具体)类?您尝试过吗
template<class Graph, class NodeAttribs, class ArcAttribs> string
graphToGraphviz(Graph &graph,
NodeAttribs *nattribs = (<NodeAttribsClass>*)NULL,
ArcAttribs *aattribs = (<ArcAttribsClass>*)NULL,
string name = ""){
/*...*/
}
模板字符串
graphToGraphviz(图形和图形,
NodeAttribs*nattribs=(*)NULL,
ArcAttribs*aattribs=(*)空,
字符串名称=”){
/*...*/
}
或
模板字符串
graphToGraphviz(图形和图形,
NodeAttribs*nattribs=NULL,
ArcAttribs*aattribs=NULL,
字符串名称=”){
/*...*/
}
其中
NodeAttribsClass
和ArcAttribsClass
是可在该插槽中使用的有效(具体)类?编译器在调用时出现问题:
graphToGraphviz(g);
现在,NodeAttribs
和ArcAttribs
的类型是什么?不管您是否在使用它,编译器都必须推断它的类型。因为使用或不使用是运行时检查。
使用当前代码,上述类型将变得不可推断 我怎么能编写这样的重载函数呢 你的问题有答案
重载
模板
函数,从原始模板函数中删除默认参数,并让这两个函数共存:
template<class Graph>
string graphToGraphviz(Graph &graph, string name = "");
模板
字符串graphToGraphviz(图形和图形,字符串名称=”);
编译器在调用时出现问题:
graphToGraphviz(g);
现在,NodeAttribs
和ArcAttribs
的类型是什么?不管您是否在使用它,编译器都必须推断它的类型。因为使用或不使用是运行时检查。
使用当前代码,上述类型将变得不可推断 我怎么能编写这样的重载函数呢 你的问题有答案
重载
模板
函数,从原始模板函数中删除默认参数,并让这两个函数共存:
template<class Graph>
string graphToGraphviz(Graph &graph, string name = "");
模板
字符串graphToGraphviz(图形和图形,字符串名称=”);
如果您使用的是C++11,则可以执行以下操作:
template<class Graph, class NodeAttribs=Empty, class ArcAttribs=Empty> ...
模板。。。
我在标准中没有找到相关的语言,但gcc接受它。如果您使用的是C++11,您可以这样做:
template<class Graph, class NodeAttribs=Empty, class ArcAttribs=Empty> ...
模板。。。
我在标准中没有找到相关的语言,但gcc接受它。您对
空类的想法可能是最简单的。您也可以使用部分专门化,但这可能是过度的,这取决于代码的复杂性。@rodrigo:您不能对函数进行部分专门化。@n.m:哦,对了!但是,您可以使用某种类型的traits
类并对其进行部分专门化……您对Empty
类的想法可能是最简单的。您也可以使用部分专门化,但这可能是过度的,这取决于代码的复杂性。@rodrigo:您不能对函数进行部分专门化。@n.m:哦,对了!但是,您可以使用某种类型的traits
类,并对它们进行部分专门化……当然,这种重载将是最简单的方法,但是想象一下代码,它几乎是不可分割的,我想从重载的代码调用基函数。那我又面临问题了。@Danilo不,你不是。在重载参数中,可以显式指定模板参数,例如:returngraphtoviz(graph,NULL,NULL,name)
当然可以,但是您面临着与我所问的相同的问题—在编译return graphToViz(graph,NULL,NULL,name)的过程中代码>编译器抛出错误,他无法解析NULL的模板类型。当然,这种重载将是最简单的方法,但是想象一下代码,它几乎不可分割,我想从重载的代码中调用基函数。那我又面临问题了。@Danilo不,你不是。在重载参数中,可以显式指定模板参数,例如:returngraphtoviz(graph,NULL,NULL,name)
当然可以,但是您面临着与我所问的相同的问题—在编译return graphToViz(graph,NULL,NULL,name)的过程中代码>编译器抛出无法解析NULL模板类型的错误。我尝试过此版本,但它对我不起作用-请查看我添加到第一篇文章的源代码。我尝试过此版本,但它对我不起作用-请查看我添加到第一篇文章的源代码。我尝试过此版本,但它对我不起作用不起作用-请查看我附加到问题的源代码。函数中有错误