Why does the standard library have a template<>? [duplicate] - c++

This question already has answers here:
What is the meaning of template<> with empty angle brackets in C++?
(3 answers)
Closed 1 year ago.
I saw code in the standard library where the template was declared but the typename was not specified.
https://gcc.gnu.org/onlinedocs/libstdc++/libstdc++-html-USERS-4.2/cpp__type__traits_8h-source.html
00211 template<>
00212 struct __is_integer<int>
00213 {
00214 enum { __value = 1 };
00215 typedef __true_type __type;
00216 };
A name used in a template declaration or definition and that is dependent on a template-parameter is assumed not to name a type unless the applicable name lookup finds a type name or the name is qualified by the keyword typename.
source: Where and why do I have to put the "template" and "typename" keywords?
If this is the following, what is the use of this code? Why did they put in a template<> that you don't use?

Thanks to #Scheff, #chris.
This is a template specialization of a template <typename T> struct __is_integer;
https://www.cplusplus.com/doc/oldtutorial/templates/
https://en.cppreference.com/w/cpp/language/template_specialization
00147 //
00148 // Integer types
00149 //
00150 template<typename _Tp>
00151 struct __is_integer
00152 {
00153 enum { __value = 0 };
00154 typedef __false_type __type;
00155 };

Related

Referencing a template from an inner class [duplicate]

This question already has answers here:
Where and why do I have to put the "template" and "typename" keywords?
(8 answers)
Closed 2 years ago.
I have the following code
template<typename VP,bool b>
class ValueProcessor{
template<typename Access,typename X> void processValue(X& x){}
};
template<typename VP>
class ValueProcessor<VP,true>{
public:
template<typename Access,typename X> void processValue(X& x);
};
template<typename VP>
template<typename Access,typename X>
void ValueProcessor<VP,true>::processValue(X& x){
class Updater{
ValueProcessor<VP,false> valPro;
X x;
public:
void operator()(){
valPro.processValue<Access,X>(x);
};
};
}
but it fails with this error
source>: In member function 'void ValueProcessor<VP, true>::processValue(X&)::Updater::operator()()':
<source>:23:32: error: expected primary-expression before ',' token
23 | valPro.processValue<Access,X>(x);
|
^
How can I refer to Access from the inner class?
As pointed out in the comment the solution is to add a .template discrimitaor before the member function name:
valPro.template processValue<Access,X>(x);
This is necessary because the type of ValueProcessor<VP,false> valPro is a dependent type (i.e. it's actual type depends on the type of the template parameter VP) the c++ language requires to add the .template disambiguator if you want to call a template member function of VP. Otherwise the parser would interpret the opening < as less-than operator.
See cppreference for a more in-depth discussion. The template disambiguator is described at the very end of that article.

Return a struct declared inside template class from a template method [duplicate]

This question already has answers here:
Where and why do I have to put the "template" and "typename" keywords?
(8 answers)
Closed 4 years ago.
I have the following:
#include <vector>
template <class T>
class A
{
public:
struct S
{
int a;
};
std::vector<S> returnStructs(void);
};
template <class T>
std::vector<A<T>::S> A<T>::returnStructs(void)
{
}
int main(void)
{
}
but when I try to compile I get:
error: template argument for template type parameter must be a type; did you forget
'typename'?
std::vector<A<T>::S> A<T>::returnStructs(void)
^
typename
so I switched out that line for:
std::vector<A<int>::S> A<T>::returnStructs(void)
^
'int' instead of 'T'
but then I get a new compiler error:
error: return type of out-of-line definition of 'A::returnStructs' differs from that in the
declaration
std::vector<A<int>::S> A<T>::returnStructs(void)
~~~~~~~~~~~~~~~~~~~~~~ ^
so any thoughts on how to fix this?
Also I realize I can just take struct S out of class A and be done with all these issues but I still feel like it should be possible to solve this without changing class A.
The first compiler error told you exactly what was wrong: did you forget 'typename'
As S is a member of a template you need to add typename to tell the compiler that it should delay the lookup of the name until after the template is resolved:
template <class T>
std::vector<typename A<T>::S> A<T>::returnStructs(void)

typedef Using a typename [duplicate]

This question already has answers here:
Where and why do I have to put the "template" and "typename" keywords?
(8 answers)
Closed 5 years ago.
So I had some code that I asked a question about which I realized was confusing and later edited out:
template <typename T>
struct foo {
typedef typename pair<T, T> PointType;
private:
PointType point;
};
I'm not certain what the function of the typename in PointType's definition is. It this keyword just omitted? I notice that it's frequently used in the using definitions to add the *_t extensions in type support. Perhaps that's what was intended here?
You are using the second type of typename use, according to cppreference: http://en.cppreference.com/w/cpp/keyword/typename
Basically, you are giving a hint to the compiler: T is a template dependent type in
pair<T, T>
It is necessary because pair<T, T> is a dependent name, meaning that it changes depending on how foo was initialized.

Template function requires existence of inner class in non-templated class [duplicate]

This question already has answers here:
Where and why do I have to put the "template" and "typename" keywords?
(8 answers)
Closed 6 years ago.
There's a template function f that requires its template parameter type T to have an inner class named Inner.
Inside f the class T::Inner shall be instantiated.
First try.
//
// "error: need 'typename' before 'T:: Inner' because 'T' is a dependent scope"
//
template <typename T>
void f( void )
{
T::Inner i;
}
I get that, so here comes the second try, where I don't get what's wrong:
/// "error: expected ';' before 'i'
template<typename T>
void f ( void )
{
typename T::Inner I;
I i;
}
Why is that?
In my understanding:
Inner is declared as type.
The template has not yet been instantiated.
Whether the type Inner exists or not first becomes relevant
on instantiation - not definition. Where am I going wrong?
I think you want to do
typename T::Inner i;
or
typedef typename T::Inner I;
I i;
whereas what you have in the question actually declares I to be a variable, and then right after that you are trying to use it as though it's a type.

How can a type alias with using specify a template template argument dependent on a template argument? [duplicate]

This question already has answers here:
Where and why do I have to put the "template" and "typename" keywords?
(8 answers)
Closed 8 years ago.
Minimal example:
template<template<class ...> class>
struct templ {};
template<class T>
using special = templ<T::type>;
int main() {}
clang++:
test.cpp:5:23: error: template argument for template template parameter must be a class template or type alias template
using special = templ<T::type>;
Indeed, I mean to say that T::type is a class template, e.g.
struct detail1 {
template <class T>
using type = std::vector<T>;
};
struct detail2 {
template <class T>
struct type {};
};
But how can one say this? g++ suggests to use typename T::type, but this seams wrong to me, and indeed, this does not solve the error.
You need to specify that type is a template:
template<class T>
using special = templ< T::template type>;
This is needed because T::type is dependent on the template parameter T.
See also Where and why do I have to put the “template” and “typename” keywords?