将类型参数传递给自引用指针

Man*_*att 9 c++ templates class definition

template <class T>
class Node {
    private:
        T m_value;
        //Node* m_ptr;    //(1)
        //Node<T>* m_ptr; //(2)
};
Run Code Online (Sandbox Code Playgroud)

有人可以解释上述两个陈述(1)和(2)之间的区别吗?这两个语句似乎都在编译,但我似乎无法找到ISO C++对它们所说的内容.

Max*_*mer 10

它们是相同的,因为你在模板中声明指针,因此当你创建Node编译器的实例知道什么T是.如果可以推导出模板的类型,则不必指定模板的类型,例如,从参数类型,或者在这种情况下,指针所属的模板实例.

template <class T>
class Node {
public:
    T m_value;
    Node* m_ptr;    //(1)
    //Node<T>* m_ptr; //(2)
};

int main()
{
    Node<float> test;
    test.m_ptr = new Node<float>{}; // valid
    test.m_ptr = new Node<bool>{};  // invalid - triggers compiler error
    auto val = test.m_ptr->m_value; // val will be of float type
}
Run Code Online (Sandbox Code Playgroud)


Vla*_*cow 9

根据C++标准(14.6.1本地声明的名称)

3类模板或类模板特化的inject-class-name 可以用作模板名称或类型名称, 只要它在范围内.[例如:

template <class T> struct Base {
Base* p;
};
template <class T> struct Derived: public Base<T> {
typename Derived::Base* p; // meaning Derived::Base<T>
};
template<class T, template<class> class U = T::template Base> struct Third { };
Third<Base<int> > t; // OK: default argument uses injected-class-name as a template
Run Code Online (Sandbox Code Playgroud)

- 结束例子]

因此这些数据成员声明

Node* m_ptr;    //(1)
Node<T>* m_ptr; //(2)
Run Code Online (Sandbox Code Playgroud)

是等价的,因为注入的类名Node在类定义的范围内使用.