Dependent scope and nested templates
The C++ grammar is horrendous, and as such it is not possible, when given a template class, to know whether the ::node
you refer to is a variable/constant or a type.
The Standard therefore mandates that you use typename
before types to remove this ambiguity, and treats all other usages as if it was a variable.
Thus
template <typename T, int degree>
typename btree<T,degree>::node* btree<T,degree>::findLead(T const& value)
^~~~~~~~
is the correct signature for the definition.
Nested templates with dependent scope
The compiler told you exactly what to do. Write typename
before ptrModel<std::vector<Data> >::Type
, like so:
typedef typename ptrModel<std::vector<Data> >::Type Type;
The reason for this requirement is that the compiler doesn't at this point know whether ptrModel<std::vector<Data> >::Type
describes a member variable or a nested type. It can't even figure that out by looking at the definition of ptrModel
because there might be a specialization of ptrModel
for std::vector<Data>
somewhere else in the program that it hasn't gotten to yet which changes which of these things ::Type
refers to. So you need to tell it explicitly.
The name ptrModel<std::vector<Data> >::Type
has a "dependent scope" because it is in a scope that depends on the instantiation of a template.
typedef typename and Dependent scope
Your Ideone sample fixed:
#include <iostream>
#include <vector>
#include <iterator>
template<typename _Tp, typename _Alloc = std::allocator<_Tp> >
class PtrVector
{
private:
typedef std::vector<_Tp, _Alloc> VectrorT;
typedef typename std::vector<_Tp, _Alloc>::const_iterator VTConstIter;
// ^^^^^^^^ ^^^^^^^^^^^^^^^^
public:
typename std::vector<_Tp, _Alloc>::const_iterator test(){}
// ^^^^^^^^ ^^^^^^^^^^^^^^^^
VTConstIter test2(){}
};
int main() {
return 0;
}
As for your comments, see these variants also:
// ...
typedef typename VectrorT::const_iterator VTConstIter; // also works
// ...
typename VectrorT::const_iterator test(){} // also works
// ...
I hope that clarifies abit further what's going on in the compilers guts.
need ‘typename’ before ‘..’ because ‘..’ is a dependent scope
There is no member called dataType
, I assume the return type should be just the template dataType
:
template <typename dataType>
dataType Node<dataType>::getData() const {
return nodeData;
}
The compiler message is misleading in this case as it doesn't find proper definition, it assumes the dataType
refers to the template argument.
Is a local class dependent if declared within a function template?
According to my understanding (and the current wording of the standard), C
in your example is not dependent. Neither is A<C>::Type
, so the typename
is not required.
There is a fundamental difference between nested classes of class templates and local classes in function templates: The latter cannot be specialized, thus any reference to a local class inside a function template is uniform. That is, in every specialization of f
, C
refers to the class C
that is defined in this function template f
. That is not the case with class templates as you can indeed explicitly specialize members on their own (as covered in [temp.expl.spec]
/(1.6)):
template <typename T>
class A { class C{}; };
template <>
class A<int>::C { int i; };
However:
A type is dependent if it is
- a compound type constructed from any dependent type,
So if the definition was done as in dyp's example, C
would be dependent as it is constructed from T
.
There are unclarities in the standards wording that are being discussed in the comment section, e.g. about definitions of member functions that depend on T
and how that transposes to the classes dependency.
dependent scope; need typename in front;
The compiler says
my_vector.h:21:2: error: need ‘typename’ before
‘std::vector::iterator’ because ‘std::vector’ is a
dependent scope
So you need to write
typename vector< a_type >::iterator vec1_pre = vec1.begin();
typename vector< a_type >::iterator vec1_pos = vec1.begin();
See Where and why do I have to put the "template" and "typename" keywords? for the reasons behind it.
One last remark: In C++11 you can use auto
and don't have to think anymore:
auto vec1_pre = vec1.begin();
auto vec1_pos = vec1.begin();
C++ Non-Template Used as Template - Nested Template Classes
Add template keyword before LinkedListIterator so compiler knows it is a template and not e.g. a field
template <typename T>
template <typename NodeType>
const typename LinkedList<T>::template LinkedListIterator<NodeType>&
LinkedList<T>::LinkedListIterator<NodeType>::operator++()
{
// Implementation here
}
Related Topics
Converting a Row of Cv::Mat to Std::Vector
Is It Legal for a C++ Optimizer to Reorder Calls to Clock()
Switch Passed Type from Template
C++11 Memory_Order_Acquire and Memory_Order_Release Semantics
How to Do a #Define Inside of Another #Define
Inspecting Stl Containers in Visual Studio Debugging
Std::Copy to Std::Cout for Std::Pair
When to Use Extern "C" in Simple Words
What's the C++ Suffix for Long Double Literals
Using 'Const' in Class's Functions
I Want to Kill a Std::Thread Using Its Thread Object
How Can Std::Bitset Be Faster Than Std::Vector<Bool>