typedef Using a typename [duplicate] - c++

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.

Related

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

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 };

c++ : meaning of keyword "typename" in this function [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.
In this answer from this question the author posted this code:
template <typename... Ts>
typename std::tuple_element<0, std::tuple<Ts...> >::type // or decltype(auto)
callFunction(Ts&&... ts)
{
using type = typename std::tuple_element<0, std::tuple<Ts...> >::type;
auto it = multiCache.find(typeid(type));
assert(it != multiCache.end());
auto&& fn = boost::any_cast<const std::function<type(Ts...)>&>(it->second);
return fn(std::forward<Ts>(ts)...);
}
The meaning of typename std::tuple_element<0, std::tuple<Ts...> >::type is that the returned type is the same of the first element of the first element in Ts..., right?
No, the typename keyword, for all practical purposes, means the same thing as class.
The difference is slightly semantic. In the context of a template function or a class, a typename can also be a POD, rather than a formally declared class. It literally means "any type, a POD or a class", loosely speaking.
That's what the keyword typename means in generally. In this case, this has a specific purpose:
typename std::tuple_element<0, std::tuple<Ts...> >::type
This tells the compiler to expect the "type" in a std::tuple_element<0, std::tuple<Ts...> > is also going to be class (or a typedef), as opposed to a class member.
When you have something that looks like:
classname::identifier
This can refer to either a type or a class member:
class X {
public:
typedef int y;
int z;
};
Here, X::y refers to a type, and X::z refers to a class member. When it comes to parsing templates, a C++ compiler will assume by default that "A::b" is going to refer to a class member, unless you stick a typename in front of it, in which case it'll get parsed as 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?

C++ Type traits in constructor causing error [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Where and why do I have to put the “template” and “typename” keywords?
I want to have a constructor that takes a single argument and is only enabled if the type of that argument has a member type ::t which must be a subtype of some other type. I am using type traits for this and the code looks like this:
#include <type_traits>
struct Y{};
struct X{
//Only allow if T has a type member T::t which is a subtype of Y
template <typename T>
X(T* t, std::enable_if<std::is_base_of<Y, typename T::t>::value, int>::type e = 0){}
};
However, g++ complains the following:
test/test.cpp:8:75: error: ‘std::enable_if<std::is_base_of<Y, typename T::t>::value, int>::type’ is not a type
What have I done wrong?
You have to add a typename to std::enable_if<...>::type to resolve this...

In what cases a "name" has to be prefixed with "typename"? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Where and why do I have to put "template" and "typename" on dependent names?
I know only two cases where they are used (this is template parameter dependency i think but i don't know more than these two forms) :
In parameter list i.e <typename T>
like typename X::Sub_type Xx
So there are any more cases in general , or there is some theory behind all this?
You need the typename keyword to refer to types whose name is dependent on a template argument. The exact rules for dependency are not trivial, but basically any type that is internal to any of your type or template arguments, or to the instantiation of any template with one of the arguments to your own template is dependent.
template <typename T, int I>
struct test {
typename T::x x; // internal to your argument
typename other_template<T>::y y; // to the instantiation of your template with an argument
typename another_tmpl<I>::z z; // even if the template argument is not a type
};
1>This is not the real reason as you can simply write <class T> as a replacement.
<typename T>
2> This is the real reason behind typename where it's needed before a qualified dependent type.
template <class T>
void foo() {
typename T::iterator * iter;
...
}
Without typename here, there is a C++ parsing rule that says that qualified dependent names should be parsed as non-types even if it leads to a syntax error.