我找到了一个图形的开源类库。当我将它包含在我的项目中时,它有很多错误,我试图修复它们。但是有一个编译错误我无法解决。
基类:
template <typename K, typename W, typename T>
class _base_graph
{
//...
protected:
std::map<K, T> nod;
std::list<edge> edg;
};
派生类:
template <typename K, typename T = void*>
class graph : public _base_graph<K, void*, T>
{
//...
public:
void add_edge(const K& k1, const K& k2);
};
方法体:
template <typename K, typename T>
void graph<K, T>::add_edge(const K& k1, const K& k2)
{
if (nod.find(k1) == nod.end() || nod.find(k2) == nod.end()) // <-- error!!
throw std::string("add_edge: Node does not exist");
// ...
}
但我的 gcc 编译器向我显示一个错误:
错误:“nod”未在此范围内声明
您可以在以下位置找到并测试 mycodethis http://ideone.com/F5u7xI在线编译器。
You need
this->nod.find(k2);
or
_base_graph<K, void*, T>::nod.find ....;
基类和派生类都是模板,并且在您的代码中nod
是一个非依赖名称,因此在以下点查找graph
的声明。这是第一阶段两阶段查找。在这个阶段,编译器(假设它遵循标准的名称查找规则)不可能知道什么nod
means, 因为它直到第二阶段才考虑基类。所以有必要告诉编译器nod
应该在第二阶段查找。为此,我们明确告诉它nod
通过使用上述形式之一位于基类中。
出现这种行为的原因是在派生类'定义,应该不可能知道什么_base_graph<K, void*, T>::
包含,以允许添加甚至隐藏名称的模板专业化。因此,上面的技巧可以确保当所有信息都可用时,在派生类实例化时查找名称。
总而言之,这里有两个问题:
-
nod
不是依赖名称,因此将在第一阶段查找它。
- 基类模板,声明
nod
,直到第二阶段才可用,因此无法解析名称。
通过使用this->nod
or _base_graph<K, void*, T>::nod
,我们显式地处理依赖名称,强制查找在第二阶段进行。
参见第 7 点至第 10 点here http://womble.decadent.org.uk/c++/template-faq.html#two-phase.
感谢@DavidRodriguez-dribeas 澄清了两阶段查找的一些细节。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)