这是我想要"使用"的情况吗?

Lai*_*ura 2 c++ inheritance templates typedef c++11

我不熟悉C++ 0x.我大约6个月前就开始学习C++了,虽然我对初学者有很强的掌握.

我有一个模板类:

template <typename T>
class Node
{
   ...
}
Run Code Online (Sandbox Code Playgroud)

然后,我有这个:

template <typename T>
class BinaryTree
{
    protected:
       typedef Node<T>* node_t;
    ...
}
Run Code Online (Sandbox Code Playgroud)

这里,二叉树类充当"基类",可以通过二叉树的特化来扩展.(AVL Tree,Red-Black等)节点typedef受到保护,因为想法是专业化将能够使用它......它们可以,但它看起来非常糟糕.

例如,在我的BiTree类(我最常用的二叉树的创意名称,基本上是BST)中,我们有:

template <typename T>
class BiTree : public BinaryTree<T>
{
   private:
      typedef typename BinaryTree<T>::node_t node_t; // Yuck
   ...
}
Run Code Online (Sandbox Code Playgroud)

更糟糕的是,我是那些喜欢在类之外指定函数的人之一,所以当我想说node_t是返回类型时...好吧,看看......

template <typename T>
typename BiTree<T>::node_t
BiTree<T>::insert(BiTree<T>::node_t& node, T data)
{
   ...
}
Run Code Online (Sandbox Code Playgroud)

有没有办法只使用node_t?这就是从基类继承typedef的重点.这是usingC++ 0x中关键字的用途吗?我将如何应用于这种情况?谢谢.

编辑:我想知道它是否有用的原因是因为这个问题:C++模板typedef

Den*_*ose 8

你的问题的答案是否定的,它不适用. using在上下文中,您的意思是用于重命名模板类型,同时保留其模板化特性.您有一个特定的模板实例,因此它不合适.

但是,您关注的部分内容似乎只是BiTree<T>::功能定义中过多的问题.这对我来说似乎并不坏; 你习惯于看到像这样的结构.但如果你愿意,它可以减少.

你的开始:

template <typename T> 
typename BiTree<T>::node_t BiTree<T>::insert(BiTree<T>::node_t& node, T data) 
{ ... } 
Run Code Online (Sandbox Code Playgroud)

首先,一旦你命名了这个函数,你就已经在这个类的"内部"了BiTree<T>,所以编译器会在里面查看你的参数类型.

template <typename T> 
typename BiTree<T>::node_t BiTree<T>::insert(node_t& node, T data) 
{ ... } 
Run Code Online (Sandbox Code Playgroud)

C++ 0x的另一个新功能是能够声明其参数之后等待声明函数的结果.它适用于结果类型取决于参数类型的情况,但由于与上述相同的原因,此处也很有用.编译器BiTree<T>在分析时会考虑类型:

template<typename T>
auto BiTree<T>::insert(node_t& node, T data) -> node_t
{ ... }
Run Code Online (Sandbox Code Playgroud)

几乎没有重复.从技术上讲,您可以更进一步:

template<typename T>
auto BiTree<T>::insert(node_t& node, T data) 
     -> std::remove_reference<decltype(node)>::type
{ ... }
Run Code Online (Sandbox Code Playgroud)

现在,你甚至没有重复参数类型,但是获得正确的返回类型显然更加困难[事实证明我最初错了;-)].