C++中模板类和友元类共同使用的处理方法

以一个栈链表为例,新建一个模板节点类Node

template<typename Type>
class Stack;//先声明Stack类以便于在Node类中声明友元类

template<typename Type>
class Node
{
public:
	Node() 
	{ 
		value = 0;
		next = nullptr;
	}
	Node(Type value) :value(value) { next = nullptr; }
        friend class Stack;
private:
	Type value;
	Node<Type>* next;
};

然后写模板栈类Stack

template<typename Type>
class Stack
{
private:
	Node<Type>* head;
	Node<Type>* foot;
public:
	Stack()
	{
		foot = new Node<Type>();
		head = foot;
	}
	void push(Type value)
	{
		Node<Type>* node=new Node<Type>(value);
		node->next = head;
		head = node;
	}
	Type pop()
	{
		if (foot==head)
		{
			throw "empty stack";
		}
		Node<Type>* p = head;
		Type value = head->value;
		head = head->next;
		delete p;
		return value;
	}
	Type read()
	{
		if (foot == head)
		{
			throw "empty stack";
		}
		return head->value;
	}
	bool empty()
	{
		if (foot == head)
		{
			return true;
		}
		else
		{
			return false;
		}
	}
	void print()
	{
		Node<Type>* p = head;
		while (p!=foot)
		{
			cout << p->value << " ";
			p = p->next;
		}
		cout << endl;
	}
};

编译运行,出现C2990错误: “Stack”: 非类 模板 已经声明为类 模板,查阅微软的文档,文档描述有:

由于 Microsoft C++编译器 For Visual Studio 2005 中的重大更改,也可能会发生 C2990;编译器现在要求同类型的多个声明对于模板规范是相同的。

https://docs.microsoft.com/zh-cn/cpp/error-messages/compiler-errors-2/compiler-error-c2990?f1url=https%3A%2F%2Fmsdn.microsoft.com%2Fquery%2Fdev16.query%3FappId%3DDev16IDEF1%26l%3DZH-CN%26k%3Dk(C2990)%26rd%3Dtrue&view=vs-2019

按照文档所给实例:

template<class T>
class A;

// OK
template<class T>
struct B {
   template<class T>
   friend class A;
};

即在友元类声明的上方也需要添加模板声明,所以以下写法即可正常运行

template<typename Type>
class Stack;//先声明Stack类以便于在Node类中声明友元类

template<typename Type>
class Node
{
public:
	Node() 
	{ 
		value = 0;
		next = nullptr;
	}
	Node(Type value) :value(value) { next = nullptr; }
	template<typename Type>
	friend class Stack;
private:
	Type value;
	Node<Type>* next;
};

发表评论