template <class T>
class Node {
private:
T m_value;
//Node* m_ptr; //(1)
//Node<T>* m_ptr; //(2)
};
Can someone explain what is the difference between the above two statements (1) and (2)? Both statements seem to compile, but I can't seem to find what the ISO C++ says about them.
They are the same thing, because you declare the pointer inside the template, thus when you create an instance of Node
the compiler knows what T
is. You don't have to specify the type for a template if it can be deduced, e.g. from argument types, or in this case from the template instance the pointer belongs to.
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
}
According to the C++ Standard (14.6.1 Locally declared names)
3 The injected-class-name of a class template or class template specialization can be used either as a template-name or a type-name wherever it is in scope. [ Example:
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
— end example ]
Thus these data member declarations
Node* m_ptr; //(1)
Node<T>* m_ptr; //(2)
are equivalent because the injected class name Node
is used in the scope of the class definition.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With