【发布时间】:2017-05-07 16:52:42
【问题描述】:
我浏览了该网站和其他网站上的数十篇文章,但找不到一篇解决这个特定问题的文章。考虑一下我正在研究的这个 SparseGraph 类:
Sparse_Graph.h
template <typename NodeType, typename EdgeType>
class SparseGraph
{
//...
public:
SparseGraph();
//...
};
为了缩短我的 .cpp 文件中的代码,我正在寻找类似于:
Sparse_Graph.cpp
#include "Sparse_Graph.h"
template<typename NodeType, typename EdgeType>
using SGraph = SparseGraph<NodeType, EdgeType>;
SGraph::SparseGraph() {}
这对我来说特别重要,因为稍后在这个文件中我有一个迭代器函数的声明,写成:
template <typename NodeType, typename EdgeType>
typename SparseGraph<NodeType, EdgeType>::EdgeIterator&
SparseGraph<NodeType, EdgeType>::EdgeIterator::operator++()
(是的)
特别是,我尝试这样做时遇到的错误是:
在没有参数列表的情况下无效使用模板名称“SGraph”
所以我的问题是:我怎样才能让这种事情发挥作用,这样我就不必在我的 .cpp 文件中编写 3 行函数标题?
【问题讨论】:
-
那是因为
NodeType和EdgeType是通用类型而不是实际类型。你需要说using SGraph = SparseGraph<ActualNodeType, ActualEdgeType>... (IIRC) -
模板
using SGraph = SparseGraph ::Node, SparseGraph ::Edge>;不工作。 (我在类声明中有一个 Edge 和 Node 的 using 声明)。我认为这些也不符合实际类型。 -
您不能将实现放在 .cpp 文件中,因为编译器必须能够在为具体类型实例化模板的地方看到它。 See this question.
-
一点修正。您不能将 generic 实现放在 .cpp 文件中,但您可以改为使用 explicit instantiation。
-
正确。这就是为什么大多数模板库只有标头。