Why is the keyword typename needed before qualified dependent names, and not before qualified independent names?
A name in C++ can pertain to three different tiers of entities: Types, values, and templates.
struct Foo
{
typedef int A; // type
static double B; // value
template <typename T> struct C; // template
};
The three names Foo::A
, Foo::B
and Foo::C
are examples of all three different tiers.
In the above example, Foo
is a complete type, and so the compiler knows already what Foo::A
etc. refer to. But now imagine this:
template <typename T> struct Bar
{
T::A x;
};
Now we are in trouble: what is T::A
? if T = Foo
, then T::A = int
, which is a type, and all is well. But when T = struct { static char A; };
, then T::A
is a value, which doesn't make sense.
Therefore, the compiler demands that you tell it what T::A
and T::B
and T::C
are supposed to be. If you say nothing, it is assumed to be a value. If you say typename
, it is a typename, and if you say template
, it is a template:
template <typename T> struct Bar
{
typename T::A x; // ah, good, decreed typename
void foo()
{
int a = T::B; // assumed value, OK
T::template C<int> z; // decreed template
z.gobble(a * x);
}
};
Secondary checks such as whether T::B
is convertible to int
, whether a
and x
can be multiplied, and whether C<int>
really has a member function gobble
are all postponed until you actually instantiate the template. But the specification whether a name denotes a value, a type or a template is fundamental to the syntactic correctness of the code and must be provided right there during the template definition.
Why typename keyword is not needed in template dependent nested type names in VS2015?
In c++20 typename
is not needed there. In some contexts, the need for typename
was removed, because syntactically anything there must be a type.
In particular:
A qualified name that appears in type-id, where the smallest enclosing type-id is:
- the type in a new expression that does not parenthesize its type;
Quoted source isn't directly from the standard, but pretty reliable.
Prior to c++20 typename
was needed there; it would be parsed as a value, and new value
is not valid syntax. In c++20 typename
is optional in that context.
Now, visual-studio-2015 has no c++20 features in it; what you are seeing there is MSVC's failure to properly implement c++11/c++14/c++17, not a c++20 extension.
c++ iterator with template
Add a typename
before the iterator
#include <iostream>
#include <vector>
template <class T>
void my_print(std::vector<T> input)
{
for (typename std::vector<T>::iterator pp = input.begin(); pp != input.end(); ++pp)
{
std::cout << *pp << "\n";
}
}
int main(int argc, char* argv[])
{
std::vector<int> aa(10, 9);
my_print(aa);
return 0;
}
source: http://www.daniweb.com/software-development/cpp/threads/187603/template-function-vector-iterator-wont-compile
What are second after function name in template funciton declaration?
template<typename C, typename V> //template declaration
vector<typename C::iterator> //return type (vector of iterators)
find_all //function name
(C& c, V v) //argument list
Function find_all
returns vector<typename C::iterator>
, or "vector of iterators to C".
The reason why typename
is needed is explained in this question: Why is the keyword “typename” needed before qualified dependent names, and not before qualified independent names?
A simpler example, without templates, which also uses <>
in return type:
std::vector<int> generateNNumbers(std::size_t numberOfElements)
{
std::vector<int> res;
...
return res;
}
The 'typename' word in C++
In simple words, "dependent name" in a template code is some type which is constructed within the definition of the template.
In your example, the types CVertex, CEdge, CFace, CHalfEdge are template parameters. All other names which are declared with usage of the parameters are dependent.
They can be type names but can be something else, e.g. name of the functions or variables. Compiler has to understand, whether a given dependent name is a type or a variable. It is actually compiler-dependent. To help the compiler, you add "typename" to indicate that this identifier is a type.
Imagine, that your code does not have #include <vector>
but instead uses forward declaration:namespace std { template<class T, class Alloc=allocator<T> > class vector; }
Then compiler has no idea which names within class vector are types and which are member names. It only knows that vector
is a type.
For example, in the code typename std::vector<TLoop*> m_loops;
most likely the word typename
can be omitted for most compilers because they know that vector is a type.
However, the code std::vector<TLoop*>::const_iterator
will sure require typename
: for (typename std::vector<TLoop*>::const_iterator it = loops().begin(); ...
Hope it helps.
Specifying one of base class template parameters by derived class template parameter. How to use base class's using declarations
myflt_t
defined in class a
is not visible in class b
as explained here: https://eli.thegreenplace.net/2012/02/06/dependent-name-lookup-for-c-templates
You can bring myflt_t
into class b
by without the explicit re-declaration:
using typename base_t::myfl_t
Using typedef inside template specializations
DataType
isn't actually a type. It's a instance of PaddingTrick::Type
, which is why the next line is giving you an error. You need to do:
typedef typename PaddingTrick::Type DataType;
How do you understand dependent names in C++
A dependent name is essentially a name that depends on a template argument.
When using templates there is a distinction between the point of definition of the template and the point of instantiation i.e. where you actually use the template. Names that depend on a template don't get bound until the point of instantiation whereas names that don't get bound at the point of definition.
A simple example would be:
template< class T > int addInt( T x )
{
return i + x.toInt();
}
where a declaration or definition of i
would need to appear before the definition given above since i
does not depend on the template argument T
and is therefore bound at the point of definition. The definition of the toInt
member of the as-yet-unknown-type x
variable only has to appear before the addInt
function is actually used somewhere as it is a dependent name ( technically the point of instantiation is taken as the nearest enclosing global or namespace scope just before the point of use and so it has to be available before that ).
non-type template parameter whose type depends on another parameter
You almost put the typename
in the right place.
template<typename T, typename A<T>::Pointer P>
Also, the Pointer
typedef
needs to be public in order for this to work.
Related Topics
String Literals Not Allowed as Non Type Template Parameters
What Happens When I Mix Signed and Unsigned Types
Why Is Statically Linking Glibc Discouraged
Are There Any MACros to Determine If My Code Is Being Compiled to Windows
Difference Between Using #Include<Filename> and #Include<Filename.H> in C++
"Launch Failed. Binary Not Found." Snow Leopard and Eclipse C/C++ Ide Issue
Getting the MAChine Serial Number and CPU Id Using C/C++ in Linux
How Large Is a Dword with 32- and 64-Bit Code
What Exactly Is an 'Aligned Pointer'
What Exactly Is a 'Side-Effect' in C++
Is There Any Lame C++ Wrapper\Simplifier (Working on Linux MAC and Win from Pure Code)
Differencebetween a MACro and a Const in C++
Determining Exception Type After the Exception Is Caught
Differencebetween the /Ox and /O2 Compiler Options
Popen Simultaneous Read and Write
C++ Templates Angle Brackets Pitfall - What Is the C++11 Fix
How to Make My Split Work Only on One Real Line and Be Capable to Skip Quoted Parts of String
C++ Function Callbacks: Cannot Convert from a Member Function to a Function Signature