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.
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.
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.
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.
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.
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
Check If a Variable Type Is Iterable
Accessing Environment Variables in C++
Change Default Value of Cmake_Cxx_Flags_Debug and Friends in Cmake
Function Overloading Based on Value VS. Const Reference
How to Add 2 Arbitrarily Sized Integers in C++
Why Does Gcc Generate 15-20% Faster Code If I Optimize for Size Instead of Speed
Understanding Recursion to Generate Permutations
Are Parentheses Around the Result Significant in a Return Statement
What Happens to Global Variables Declared in a Dll
Avoiding Copy of Objects with the "Return" Statement
How to Get Rid of the _Imp_ Prefix in the Linker in Vc++
How to Declare Constexpr Extern
Operator Overloading in C++ as Int + Obj