C++ 模板 class' 内部 class 访问
C++ template class' inner class access
我有一个 class 这样的:
#include <iostream>
template <class T>
class LL
{
using size_t = unsigned int;
class Node
{
T m_data;
Node* m_next;
Node(const T& data) :m_data{ data }, m_next{ nullptr }{}
friend std::ostream& operator<<(std::ostream& out, const Node& node)
{
out << node.m_data;
return out;
}
friend std::ostream& operator<<(std::ostream& out, const LL& ll);
friend class LL;
};
Node* m_first{ nullptr };
size_t m_size{ 0 };
Node* newNode(const T& data)
{
return new Node{ data };
}
public:
void push(const T& data)
{
Node* temp = newNode(data);
temp->m_next = m_first;
m_first = temp;
++m_size;
}
Node* head()
{
return m_first;
}
size_t size() const
{
return m_size;
}
~LL()
{
if (m_first)
{
Node* trav = m_first->m_next;
Node* foll = m_first;
while (trav)
{
delete foll;
foll = trav;
trav = trav->m_next;
}
delete foll;
}
}
friend std::ostream& operator<<(std::ostream& out, const LL& ll)
{
Node* trav = ll.m_first;
while (trav)
{
out << *trav << ' ';
trav = trav->m_next;
}
return out;
}
};
我在同一个文件中的 class 下面的其他地方也有一个函数模板,它试图访问 Node
并且看起来像这样有两个编译器错误:
template <typename T>
int getSize(LL<T>::Node* node) //C2065: node is undeclared, C3861: node is not found
{
if (node)
{
return 1 + getSize(node->m_next);
}
return 0;
} //does not compile
一段时间后,我再次尝试了两个编译器:
template <typename T>
int getSize(LL<T>::Node<T>* node) //C2065 like before, C7510: use of dependent template name must be prefixed with 'template'
{
if (node)
{
return 1 + getSize(node->m_next);
}
return 0;
} //does not compile
又过了一段时间,我尝试了下面编译好的。
template <typename T>
int getSize(typename LL<T>::template Node<T>* node)
{
if (node)
{
return 1 + getSize(node->m_next);
}
return 0;
}
现在,当我试图从我的驱动程序函数中调用这个函数时,我再次遇到编译器错误:
int main()
{
LL<int> ll;
std::cout << getSize(ll.head()); //E0304, C2672 and C2783
//E0304: no instance of the function template "getSize" matches the argument list
//C2672: no matching overload function found
//C2783: could not deduce template argument for 'T'
}
我尽我所能解决了这个问题。有人可以向我解释发生了什么事吗?
注意:我在这里提到的所有代码都在同一个文件中。
getSize(ll.head())
由于 non-deduced context 而失败;无法自动推导模板参数 T
。
If a template parameter is used only in non-deduced contexts and is not explicitly specified, template argument deduction fails.
- 1) The nested-name-specifier (everything to the left of the scope resolution operator ::) of a type that was specified using a qualified-id:
声明应该是
template <typename T>
int getSize(typename LL<T>::Node* node) // using class instead of typename works for OP (MSVC)
{
//some code
}
并且由于 Node
不是模板,因此您不需要使用 template
关键字。
请参阅 Where and why do I have to put the “template” and “typename” keywords? 了解为什么使用关键字 typename
和 template
。
我有一个 class 这样的:
#include <iostream>
template <class T>
class LL
{
using size_t = unsigned int;
class Node
{
T m_data;
Node* m_next;
Node(const T& data) :m_data{ data }, m_next{ nullptr }{}
friend std::ostream& operator<<(std::ostream& out, const Node& node)
{
out << node.m_data;
return out;
}
friend std::ostream& operator<<(std::ostream& out, const LL& ll);
friend class LL;
};
Node* m_first{ nullptr };
size_t m_size{ 0 };
Node* newNode(const T& data)
{
return new Node{ data };
}
public:
void push(const T& data)
{
Node* temp = newNode(data);
temp->m_next = m_first;
m_first = temp;
++m_size;
}
Node* head()
{
return m_first;
}
size_t size() const
{
return m_size;
}
~LL()
{
if (m_first)
{
Node* trav = m_first->m_next;
Node* foll = m_first;
while (trav)
{
delete foll;
foll = trav;
trav = trav->m_next;
}
delete foll;
}
}
friend std::ostream& operator<<(std::ostream& out, const LL& ll)
{
Node* trav = ll.m_first;
while (trav)
{
out << *trav << ' ';
trav = trav->m_next;
}
return out;
}
};
我在同一个文件中的 class 下面的其他地方也有一个函数模板,它试图访问 Node
并且看起来像这样有两个编译器错误:
template <typename T>
int getSize(LL<T>::Node* node) //C2065: node is undeclared, C3861: node is not found
{
if (node)
{
return 1 + getSize(node->m_next);
}
return 0;
} //does not compile
一段时间后,我再次尝试了两个编译器:
template <typename T>
int getSize(LL<T>::Node<T>* node) //C2065 like before, C7510: use of dependent template name must be prefixed with 'template'
{
if (node)
{
return 1 + getSize(node->m_next);
}
return 0;
} //does not compile
又过了一段时间,我尝试了下面编译好的。
template <typename T>
int getSize(typename LL<T>::template Node<T>* node)
{
if (node)
{
return 1 + getSize(node->m_next);
}
return 0;
}
现在,当我试图从我的驱动程序函数中调用这个函数时,我再次遇到编译器错误:
int main()
{
LL<int> ll;
std::cout << getSize(ll.head()); //E0304, C2672 and C2783
//E0304: no instance of the function template "getSize" matches the argument list
//C2672: no matching overload function found
//C2783: could not deduce template argument for 'T'
}
我尽我所能解决了这个问题。有人可以向我解释发生了什么事吗? 注意:我在这里提到的所有代码都在同一个文件中。
getSize(ll.head())
由于 non-deduced context 而失败;无法自动推导模板参数 T
。
If a template parameter is used only in non-deduced contexts and is not explicitly specified, template argument deduction fails.
- 1) The nested-name-specifier (everything to the left of the scope resolution operator ::) of a type that was specified using a qualified-id:
声明应该是
template <typename T>
int getSize(typename LL<T>::Node* node) // using class instead of typename works for OP (MSVC)
{
//some code
}
并且由于 Node
不是模板,因此您不需要使用 template
关键字。
请参阅 Where and why do I have to put the “template” and “typename” keywords? 了解为什么使用关键字 typename
和 template
。