如何解决以下错误?
这是一个链接错误,它表明您已经宣告但尚未确定(或定义不链接)以下过载:
std::ostream& operator<<(std::ostream&, node<weight>&);
常见的检查,从这里办将核查是否你有一个定义,该定义签名是否申报相匹配(你有没有宣布,但定义的运营商采取一个const引用?),定义是否被编译和链接...
我只是得到了一些时间并且实际上阅读了代码,我将基本上将其浓缩到:
template <typename T>
struct node {
friend std::ostream& operator<<(std::ostream&, node<T>&); // [1] !!!!
};
template <typename T>
std::ostream& operator<<(std::ostream& o, node<T>& n) {} // [2]
这是一个常见的错误,也是为什么它更简单的原因之一就是将模板中的朋友函数的定义与他们联系起来。基本上,在[1]模板被声明(和结交)非模板函数接受一个ostream&
和node<T>&
对象。
的这里微妙之处在于,当模板实例为某些特定类型,并且friend
声明被处理,T
是固定的,并且该行协助一个自由非模板化的功能。例如,如果你实例node
与int
,如node<int> n
,编译器将注入int
并用它代替T
,那么friend
声明将是:friend ostream& operator<<(ostream&, node<int>&)
,而这又声称,在该封闭命名空间的自由函数。制作该声明明确(并假设你只有int
实例化的模板,你的代码被编译器作为阅读:
template <typename T> struct node {
friend ostream& operator<<(ostream&, node&); // [1] note <T> not required here
};
// instantiating with int:
ostream& operator<<(ostream&, node<int>&); // [3] declaration, not definition
template <typename T>
ostream& operator<<(ostream&, node<T>&) {} // [2] your definition
在这一点上,只要您输入std::cout << a_int_node;
编译器将考虑所有重载,它会找到一个非模板免费功能[3]这是一个完美的匹配,和模板化版本[2],但非模板版本为准。编译器不会实例化模板operator<<
并期待您手动定义函数在一个翻译单元。
解决方案
最简单最好的解决办法是有编译器生成的免费功能为您服务。您只需提供模板类里面的运营商定义,一切都会好的和简单:
template <typename T>
struct node {
friend std::ostream& operator<<(std::ostream& o, node& n) // [1]
{ /* code goes here */ return o; }
};
即使代码是因为friend
在那里,你实际上声明和定义函数的模板中,在命名空间级别。如果您使用int
实例化模板,则编译器将在封闭名称空间中为您生成:std::ostream& operator<<(std::ostream&, node<int>&)
。
这个解决方案是最好的:您只授予对单个代码段的访问权限,编译器会处理大部分血腥细节。
另一方面,你可以结交一个完整的模板函数。该语法是:
template <typename T>
struct node {
template <typename U>
friend std::ostream& operator<<(std::ostream&, node<U>&); // [4]
};
template <typename T>
std::ostream& operator<<(std::ostream& o, node<T>& n) // can access private parts
{ /* code goes here */ return o; }
在这种情况下,您打开的node
所有实例的模板功能,语义是开放类的其他用户的所有实例。
第三个选项是结交了一个模板实例化,这将具有与代替非模板免费功能,您使用的是模板化的一个唯一的区别第一个选项相同的效果。在另一方面,语法是相当比较繁琐,因为它需要结交之前声明函数模板,而这又需要声明类模板:
template <typename T> struct node; // forward declare the class template
template <typename T>
std::ostream& operator<<(std::ostream&, node<T>&); // declare function template
template <typename T>
struct node { // define class template
friend std::ostream& operator<< <>(std::ostream&, node<T>&); // befriend instantiation
};
template <typename T>
std::ostream& operator<<(std::ostream& o, node<T>& n) // define function template
{ ... }
正如你看到的,最简单的最好的解决办法是刚刚定义类定义中的函数模板。
CONIO.H是从MS-DOS的编译器的旧的头;更新:但它仍然在VS 2010中可用。
最好是你用过之后你宣布一个流。
@ user597272:尝试以Unicode再次编译(进入属性,并设置为多字节) – fazo 2011-03-07 11:43:22
thts bcoz我还没有accpted的答案是这仍然是尚未解决的相同的代码... – digster 2011-03-07 11:51:27
@user:请不要张贴链接到代码。相反,创建一个**最小**工作示例(重现错误的示例)并直接在您的问题中发布。同样的错误 - 请不要截图,而是使用纯文本。 – 2011-03-07 12:00:52