Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/158.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 默认模板参数为Null_C++_Templates_C++11_Overloading_Default - Fatal编程技术网

C++ 默认模板参数为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,

为什么在模板化函数中不可能使用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模板类型的错误。我尝试过此版本,但它对我不起作用-请查看我添加到第一篇文章的源代码。我尝试过此版本,但它对我不起作用-请查看我添加到第一篇文章的源代码。我尝试过此版本,但它对我不起作用不起作用-请查看我附加到问题的源代码。函数中有错误