How to access hidden template in unnamed namespace? - c++

Here is a tricky situation, and i wonder what ways there are to solve it
namespace {
template <class T>
struct Template { /* ... */ };
}
typedef Template<int> Template;
Sadly, the Template typedef interferes with the Template template in the unnamed namespace. When you try to do Template<float> in the global scope, the compiler raises an ambiguity error between the template name and the typedef name.
You don't have control over either the template name or the typedef-name. Now I want to know whether it is possible to:
Create an object of the typedefed type Template (i.e Template<int>) in the global namespace.
Create an object of the type Template<float> in the global namespace.
You are not allowed to add anything to the unnamed namespace. Everything should be done in the global namespace.
This is out of curiosity because i was wondering what tricks there are for solving such an ambiguity. It's not a practical problem i hit during daily programming.

I know it somewhat spoils your point, but I really think the main trick is to avoid something like this like the plague.

Using C++0x:
namespace {
template<class T> struct Template { };
}
typedef Template<int> Template;
#include<iostream>
template<typename T>
void PrintType() {
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
template<typename FullType, typename NewParameter>
class Rebind {
template<template<class> class Template, typename OldParameter>
static Template<NewParameter> function(Template<OldParameter>);
public:
typedef decltype(function(FullType())) NewType;
};
int main()
{
PrintType< ::Template>();
PrintType<Rebind< ::Template, float>::NewType>();
return 0;
}
With gcc45 that yields
void PrintType() [with T = <unnamed>::Template<int>]
void PrintType() [with T = <unnamed>::Template<float>]
Apparently it compiles with Cormeau, but I only have access to their online test, so I'm stuck just assuming it functions as expected.
I couldn't figure out any way to pass an actual type to a struct directly and have it degrade into a template type, but the compiler had no problems stripping the two when it had to guess at function parameters. Maybe this works in C++03 using boost::result_of instead of decltype, but I've never used it before so I figured I'd stick to what I know.
Note the spacing within main. Rebind<::Template, float>::NewType gets gobbled by the parser because of <: being a digraph. I think it gets turned into Rebind[:Template, float>::NewType. So the space before ::Template is vital.
As an aside, I had no idea nested template parameters couldn't use typename [template<template<typename> class T> rather than template<template<typename> typename T>]. I think I relearn that every time I try to remember the syntax for the construct.

It's possible to access the global typedefed template by being explicit about the namespace, ie
::Template a
is a Template<int> from the anonymous namespace. Not sure if you can get a Template<float>.
Surprisingly Clang's C++ compiler is fine with the following, probably not standard behaviour:
#include <iostream>
namespace {
template <class T>
struct Template {T value;};}
typedef Template<int> Template;
int main(){
::Template a;
Template<float> b;
a.value = 6;
b.value = 3.14;
std::cout<<a.value<<" "<<b.value<<"\n";
}

disclaimer: I don't know why you'd want to do this and would probably speak sternly to someone who did.
namespace
{
template <typename T> class Template { };
}
typedef Template<int> IntTemplate;
typedef Template<float> FloatTemplate;
typedef IntTemplate Template;
int main() {
::Template t;
FloatTemplate ft;
}

Related

How to decompose a pointer-to-member in C++ (get class and member types)?

I have this scenario:
#include <iostream>
class SomeClass
{
public:
int _int;
};
#define DO_SOME_STUFF(ptr) std::cout << /* Print the typeid().hash_code() of the type which ptr is poiting to (int) */;
int main()
{
int SomeClass::* ptr_to_int_member = &SomeClass::_int;
DO_SOME_STUFF(ptr_to_int_member)
}
I want to know which type is ptr pointing at (which is currently int).
Knowing which class owns that int is also useful (which is currently SomeClass).
You can do that with a "template trick":
template<typename T>
struct PointerToMemberDecomposer {};
template<typename T, typename P>
struct PointerToMemberDecomposer<P T::*>
{
using ClassType = T;
using MemberType = P;
};
And change your code to:
#include <iostream>
template<typename T>
struct PointerToMemberDecomposer {};
template<typename T, typename P>
struct PointerToMemberDecomposer<P T::*>
{
using ClassType = T;
using MemberType = P;
};
class SomeClass
{
public:
int _int;
};
#define DO_SOME_STUFF(ptr) std::cout << typeid(PointerToMemberDecomposer<decltype(ptr)>::MemberType).hash_code();
int main()
{
int SomeClass::* ptr_to_int_member = &SomeClass::_int;
DO_SOME_STUFF(ptr_to_int_member)
}
Defining a couple of templated aliases can make the code a little bit cleaner:
#define GET_POINTER_TO_MEMBER_CLASS_TYPE(ptr) PointerToMemberDecomposer<decltype(ptr)>::ClassType
#define GET_POINTER_TO_MEMBER_MEMBER_TYPE(ptr) PointerToMemberDecomposer<decltype(ptr)>::MemberType
So you can change DO_SOME_STUFF to:
#define DO_SOME_STUFF(ptr) std::cout << typeid(GET_POINTER_TO_MEMBER_MEMBER_TYPE(ptr)).hash_code();
Explanation
This technique is called Partial template specialization.
The second definition of PointerToMemberDecomposer will be used when a pointer-to-member type is passed as template argument; And will catch new T and P typenames. using those new typenames; It will define two type aliases (ClassType and MemberType) so T and P can be used outside of the PointerToMemberDecomposer struct.
When using PointerToMemberDecomposer; you should use decltype operator which acts like type in Python or typeof in C#. decltype(x) passes the type of x instead of x itself.
Update
As 463035818_is_not_a_number have mentioned; macros can be replaced with templated aliases
template <typename T>
using ClassTypeFromPtrToMember_t = typename PointerToMemberDecomposer<T>::ClassType;
template <typename T>
using MemberTypeFromPtrToMember_t = typename PointerToMemberDecomposer<T>::MemberType;
But you should still use decltype while DO_SOME_STUFF is a macro instead of a templated function and we cant access ptr's type directly (see 463035818_is_not_a_number's answer for templated function version of DO_SOME_STUFF):
#define DO_SOME_STUFF(ptr) std::cout << typeid(MemberTypeFromPtrToMember_t<decltype(ptr)>).hash_code();
In this case; DO_SOME_STUFF can be converted to a templated function. But you might want to for example fill a non capturing lambda with macro arguments; which requires DO_SOME_STUFF to be a macro.
Also, you might want to change ClassType and MemberType to type and create two separated structs (or classes) for retrieving those type aliases; If you want PointerToMemberDecomposer to look like C++'s standard library.
For more details; see 463035818_is_not_a_number's answer
Just summarizing comments to some otherwise great answer...
Member aliases are commonly named just type. Macros are better avoided (Why are preprocessor macros evil and what are the alternatives?) and for less verbosity on the caller you can use a function template:
#include <iostream>
#include <typeinfo>
template<typename T>
struct TypeFromPtrToMember; // needs no definition
template<typename T, typename P>
struct TypeFromPtrToMember<P T::*>
{
using type = T;
};
class SomeClass
{
public:
int _int;
};
template <typename T>
void do_some_stuff(T t){
std::cout << typeid(typename TypeFromPtrToMember<T>::type).hash_code();;
}
int main()
{
int SomeClass::* ptr_to_int_member = &SomeClass::_int;
do_some_stuff(ptr_to_int_member);
}
Naming the member alias type is so common that I would do it even if you then need two traits. The other trait is basically the same just with using type = P;.
In the above, there is still the little annoyance of having to write typename when using the trait (because TypeFromPtrToMember<T>::type is a dependent name). Since C++11 we can use a template alias to help with that. Template aliases cannot be partially specialized, but we already have the trait and just need to forward to that:
template <typename T>
using TypeFromPtrToMember_t = typename TypeFromPtrToMember<T>::type;
Such that do_some_stuff can be:
template <typename T>
void do_some_stuff(T t){
std::cout << typeid(TypeFromPtrToMember_t<T>).hash_code();;
}
I hope you agree that now no macros are needed anymore.

Simulating argument-dependent lookup for template arguments

I've encountered this problem while writing some library-like code recently, and I thought discussing it might help others as well.
Suppose I have a library with some function templates defined in a namespace. The function templates work on types supplied by client code, and their inner workings can be customized based on type traits defined for the client types. All client definitions are in other namespaces.
For the simplest example possible, a library function would basically have to look like this (note that all the code snippets are just wishful thinking, nothing compiles):
namespace lib
{
template<typename T> void f()
{
std::cout << traits_for<T>::str() << '\n'; //Use the traits in some way.
}
}
Client code would look like this:
namespace client
{
struct A { };
template<> std::string traits_for<A>::str() { return "trait value"; }
}
And then someone, somewhere could call
lib::f<client::A>();
and everything would magically work (the specialization of lib::f() would find the traits explicit specialization in the namespace where the template argument for T is declared, just like ADL does for functions and their arguments). The goal is to make it as easy as possible for client code to define those traits (there could be several) for each client class (there could be lots of those).
Let's see what we could do to make this work. The obvious thing is to define a traits class primary template in lib, and then explicitly specialize it for client types. But then clients can't define those explicit specializations in their own namespace; they have to exit it, at least up to the global namespace, define the explicit specialization, then re-enter the client namespace, which, for maximum fun, could be nested. I'd like to keep the trait definitions close to each client class definition, so this namespace juggling would have to be done near each class definition. Suddenly, a one-liner in client code has turned into a messy several-liner; not good.
To allow the traits to be defined in the client namespace, we could turn the traits class into a traits function, that could be called from lib like this:
traits_for(T())
but now we're creating an object of class T just to make ADL kick in. Such objects could be expensive to construct (or even impossible in some circumstances), so this isn't good either. We have to keep working with types only, not their instances.
Giving up and defining the traits as members of the client classes is not an option either.
Some plumbing required to make this work would be acceptable, as long as it doesn't complicate the definitions for each class and trait in the client namespace (write some code once, but not for every definition).
I've found a solution that satisfies these stringent requirements, and I'll write it up in an answer, but I'd like to find out what people think about this: alternatives, critique of my solution, comments about how all of this is either bleeding obvious or completely useless in practice, the works...
To find a declaration based on some argument, ADL looks like the most promising direction. So, we'll have to use something like
template<typename T> ??? traits_helper(T);
But we can't create objects of type T, so this function should only appear as an unevaluated operand; decltype springs to mind. Ideally, we shouldn't even assume anything about T's constructors, so std::declval could also be useful:
decltype(traits_helper(std::declval<T>()))
What could this do? Well, it could return the actual traits type if the helper would be declared like this:
template<typename T> traits_for<T> traits_helper(T);
We've just found a class template specialization in another namespace, based on the declaration of its argument.
EDIT: Based on a comment from Yakk, traits_helper() should take a T&&, to allow it to work if T's move constructor is not available (the function may not actually be called, but the semantic constraints required for calling it must be met). This is reflected in the complete sample below.
All put together in a standalone example, it looks like this:
#include <iostream>
#include <string>
#include <utility>
namespace lib
{
//Make the syntax nicer for library code.
template<typename T> using traits_for = decltype(traits_helper(std::declval<T>()));
template<typename T> void f()
{
std::cout << traits_for<T>::str() << '\n';
}
}
namespace client_1
{
//The following two lines are needed only once in every client namespace.
template<typename> struct traits_for { static std::string str(); };
template<typename T> traits_for<T> traits_helper(T&&); //No definition needed.
struct A { };
template<> std::string traits_for<A>::str() { return "trait value for client_1::A"; }
struct B { };
template<> std::string traits_for<B>::str() { return "trait value for client_1::B"; }
}
namespace client_2
{
//The following two lines are needed only once in every client namespace.
template<typename> struct traits_for { static std::string str(); };
template<typename T> traits_for<T> traits_helper(T&&); //No definition needed.
struct A { };
template<> std::string traits_for<A>::str() { return "trait value for client_2::A"; }
}
int main()
{
lib::f<client_1::A>(); //Prints 'trait value for client_1::A'.
lib::f<client_1::B>(); //Prints 'trait value for client_1::B'.
lib::f<client_2::A>(); //Prints 'trait value for client_2::A'.
}
Note that no objects of type T or traits_for<T> are created; the traits_helper specialization is never called - only its declaration is used.
What's wrong with just requiring clients to throw their specializations in the right namespace? If they want to use their own, they can:
namespace client
{
struct A { };
struct traits_for_A {
static std::string str() { return "trait value"; }
};
}
namespace lib
{
template <>
struct traits_for<client::A>
: client::traits_for_A
{ };
}
Could even give your users a macro if you don't want them to write all that out:
#define PROVIDE_TRAITS_FOR(cls, traits) \
namespace lib { \
template <> struct traits_for<cls> : traits { }; \
}
So the above can become
PROVIDE_TRAITS_FOR(client::A, client::traits_for_A)
ADL is awesome. Keep it simple:
namespace lib {
// helpers for client code:
template<class T>
struct default_traits{
using some_type=void;
};
struct no_traits{};
namespace details {
template<class T,class=void>
struct traits:lib::no_traits{};
template<class T>
struct traits<T,decltype(void(
traits_func((T*)0)
))>:decltype(
traits_func((T*)0)
){};
}
template<class T>
struct traits:details::traits<T>{};
}
Now simply add in the type Foo namespace:
namespace bob{
// use custom traits impl:
struct foo{};
struct foo_traits{
using some_type=int;
};
foo_traits traits_func(foo const*);
// use default traits impl:
struct bar {};
lib::default_traits<bar> traits_func(bar const*);
// use SFINAE test for any type `T`:
struct baz {};
template<class T>
std::enable_if_t<
std::is_base_of<T,baz>{},
lib::default_traits<T>
>
traits_func(T const*)
}
and we are done. Defining traits_func that takes a pointer convertable from foo* is enough to inject the trait.
If you fail to write such an overload, we get an empty traits, which is SFINAE friendly.
You can return lib::no_traits in an overload to explicitly turn off support, or just don;t write an overload that matches a type.

Prevent templated member function from being instantiated for a given type

I have a templated matrix class that I explicitly instantiate for various POD types and custom class types. Some of the member functions however don't make sense for a few of such custom types. For example:
Matrix<int> LoadFile(....); // This makes sense
Matrix<My_custom_class> LoadFile(...); //This doesn't make sense in the context of the custom class
Can I prevent the instantiation of the LoadFile function (which is a member function) for Matrix objects of select types? So far I have avoided the issue by making LoadFile a friend function and then explicitly controlling its instantiation. But I want to know if I can do this when LoadFile is a member function of Matrix.
The first question is whether you really need to control this. What happens if they call that member function on a matrix that stores My_custom_class? Can you provide support in your class (or the template) so that the member function will work?
If you really want to inhibit the use of those member functions for some particular type, then you can use specialization to block the particular instantiation:
template <typename T>
struct test {
void foo() {}
};
template <>
inline void test<int>::foo() = delete;
Or even just add static_asserts to the common implementation verifying the preconditions for what types is it allowed or disallowed?
template <typename T>
struct test {
void foo() {
static_assert(std::is_same<T,int>::value || std::is_same<T,double>::value,
"Only allowed for int and double");
// regular code
}
};
with std::enable_if, this is the best I can come up with
template< typename T >
struct Matrix {
template< typename T >
Matrix< typename std::enable_if<std::is_integral<T>::value, T>::type >
LoadFile()
{
return Matrix<T>();
}
};
Matrix<int> a;
Matrix<int> b = a.LoadFile<int>()
only type int compile while other don't.
Can I prevent the instantiation of the LoadFile function (which is a member function) for Matrix objects of select types?
Your best bet here would be to use a static_assert that would create a compiler error when you attempt to call the method in a version of the class instantiated with a blocked type. Using std::enable_if, and other methods that would selectively "disable" a method itself would require you to create partial or full specializations of the class with and without the methods in question in order to prevent compiler errors. For instance, AFAIK, you cannot do the following:
template <typename T>
struct test
{
static const bool value = false;
};
template<>
struct test<double>
{
static const bool value = true;
};
template<typename T>
struct example
{
void print() { cout << "Printing value from print()" << endl; }
typename enable_if<test<T>::value, T>::type another_print()
{
cout << "Printing value from another_print()" << endl;
return T();
}
};
If you attempted to instantiate an example<int>, etc., you would end up with a compiler error at the point of instantiation of the object type. You couldn't simply call example<int>::print() and be okay, and only run into a problem if you chose to call example<int>::another_print(). Specializations of example<T> could get you around the issue, but that can be a bit of a mess. As originally surmised, a static_assert would probably be the easiest case to handle, along with a nice message to the end-user explaining what went wrong.
Keep in mind that creating compiler errors is the goal, and it's a good one to have. If you blocked a method from being instantiated, and the end-user decided to invoke it, you'd end up with a compiler error either way. The version without the static_assert will leave a lot of head-scratching as the user of your class attempts to parse a probably very verbose compiler error message, where-as the static_assert method is direct and to the point.
If the selected set of types is known at compile time, and you are using c++11 with a compiler that supports type aliases, uniform initialization and constexpr (for example gcc 4.7) you can make your code a bit cleaner like this (from previous example above by yngum):
template <bool Cond, class T = void>
using enable_if_t = typename std::enable_if<Cond, T>::type;
template< typename T >
struct Matrix {
template< typename T >
//std::is_integral has constexpr operator value_type() in c++11. This will work thanks to uniform init + constexpr. With the alias, no more need for typename + ::type
Matrix<enable_if_t<std::is_integral<T>{}>>
LoadFile()
{
return Matrix<T>();
}
};
Matrix<int> a;
Matrix<int> b = a.LoadFile<int>();
Beware of compatibility of this code, though, because these features have been only recently supported and some compilers don't do yet. You can see more about c++11 compiler support here.
If you could use the TypeLists from the ( http://www.amazon.com/Modern-Design-Generic-Programming-Patterns/dp/0201704315 ) - Loki you could implement something like:
template<bool>
struct Static_Assert;
template<>
struct Static_Assert<true>{};
class B{};
template<typename T>
class A{
public:
A(){
Static_Assert< 0 == utils::HasType<T, TYPELIST_2(B,int) >::value >();
}
};
Then your HasType would be something like:
template<typename T, typename TList>
struct HasType{
enum { value = 0+HasType< T, typename TList::Tail >::value };
};
template<typename T>
struct HasType< T, NullType >{
enum { value = 0 };
};
template<typename T, typename U>
struct HasType< T, TypeList<T, U> >{
enum { value = 1 };
};
In the list you can add the classes which you would like prevent to be passed as the template parameters.

How can one avoid duplicating class template specification for each member function?

If I have a template class specification like so,
template <typename T>
class MyClass {
public:
void fun1();
// ...
void funN();
};
template <typename T>
void MyClass<T>::fun1() {
// definition
}
// ...
template <typename T>
void MyClass<T>::funN() {
// definition
}
If I change the class template to something else, say I add an extra parameter:
template <typename T, typename U>
class MyClass {
// ...
};
Then I have to change each function definition (fun1, ..., funN) to agree with the class template specification:
template <typename T, typename U>
void MyClass<T,U>::fun1() { //... }
Are there any strategies for avoiding this? Could I use macros e.g.
#define DFLT_TEMPLATE template<typename T, typename U>
#define DFLT_CLASS class<T,U>
DFLT_TEMPLATE
void DFLT_CLASS::fun1() { // ... }
Or is this considered bad practice?
To me, the benefits of using a macro here are far overshadowed by the drawbacks. Yes, if you use a macro then if you ever need to add an additional template parameter, you'll only need to make a single modification. But anyone else reading your code is probably going to vomit.
I mean, are you going to do this for every template you have? Your code will become infested with ugly macros.
How many member functions do you have that this is an issue?
I think either they are small enough to be defined within the class template or the adaption of their algorithms to an additional template parameter would by far outweigh the replacement of those function headers.
Also, your editor ought to do this for you in no time anyway.
yes you could but don't forget to use "#undef DFLT_TEMPLATE" and "#undef DFLT_CLASS" at the end of file to avoid compiler warnings if your project have several templates with same macros definitions
Inheritation is better than macro.
If you want to change only a few functions and variables, make the specialized class inherit a common class that provides common functions/variables.
As far as possible, put the function definitions in the class template definition. It's a template, so unless you're using Comeau compiler, it's not as if they're going to be off in a different TU.
If the functions use something which is defined in between the class definition and the function definition, then you can play tricks to make that thing dependent on a template parameter even when "really" it isn't. For example:
template <typename T>
struct Foo {
void usebar();
};
struct Bar {
int a;
Foo<int> circularity; // circular dependency between Foo and Bar
Bar() : a(3) {}
};
template <typename T> void Foo<T>::usebar() {
Bar b;
std::cout << b.a << "\n";
}
Becomes:
// we only have to write "same" once
template <typename T, typename U>
struct same {
typedef U type;
};
struct Bar;
template <typename T>
struct Foo {
void usebar() {
typename same<T,Bar>::type b;
std::cout << b.a << "\n";
}
};
struct Bar {
int a;
Foo<int> circularity; // circularity gone
Bar() : a(3) {}
};
Or actually in this case just:
struct Bar;
template <typename T, typename B = Bar>
struct Foo {
void usebar() {
B b;
std::cout << b.a << "\n";
}
};
struct Bar {
int a;
Foo<int> circularity;
Bar() : a(3) {}
};
All cases support the following code:
int main() {
Foo<int> f;
f.usebar();
}
I would consider this approach bad practice. What you are complaining about is that you have changed your design (you need an extra template parameter) and now want a kludge to save on typing?
Introducing macros is going to decrease the readability of your code. Preprocessor definitions certainly have their place, but personally I'd never advocate one on the grounds that I can't be bothered to change my functions.
There are probably some (more or less bad) workarounds, but you definitely point out a " missing" feature of C++: class namespace extension.
Some people already proposed to extend C++ in this way:
http://www.lrde.epita.fr/dload//20080709-Seminar/ordy-classnamespaces.pdf
namespace foo
{
class bar
{
typedef int baz_t;
baz_t my_method ();
};
}
namespace class foo::bar
{
baz_t my_method ()
{
// ...
}
}
--
Using a macro is not a good idea (usual things about macros ....).
I would prefer, at worst, write function members definitions inline in this case, or even better use an editor than can help you easily update your class definition.
Macros are bad because they let you write code editing functions where you are supposed to write programs.
If you want to edit code, use your editor (sed, M-x replace-*, Find&Replace ...)

Officially, what is typename for?

On occasion I've seen some really indecipherable error messages spit out by gcc when using templates... Specifically, I've had problems where seemingly correct declarations were causing very strange compile errors that magically went away by prefixing the typename keyword to the beginning of the declaration... (For example, just last week, I was declaring two iterators as members of another templated class and I had to do this)...
What's the story on typename?
Following is the quote from Josuttis book:
The keyword typename was introduced to
specify that the identifier that
follows is a type. Consider the
following example:
template <class T>
Class MyClass
{
typename T::SubType * ptr;
...
};
Here, typename is used to clarify that
SubType is a type of class T. Thus,
ptr is a pointer to the type
T::SubType. Without typename, SubType
would be considered a static member.
Thus
T::SubType * ptr
would be a multiplication of value
SubType of type T with ptr.
Stan Lippman's BLog post suggests :-
Stroustrup reused the existing class
keyword to specify a type parameter
rather than introduce a new keyword
that might of course break existing
programs. It wasn't that a new keyword
wasn't considered -- just that it
wasn't considered necessary given its
potential disruption. And up until the
ISO-C++ standard, this was the only
way to declare a type parameter.
So basically Stroustrup reused class keyword without introducing a new keyword which is changed afterwards in the standard for the following reasons
As the example given
template <class T>
class Demonstration {
public:
void method() {
T::A *aObj; // oops …
// …
};
language grammar misinterprets T::A *aObj; as an arithmetic expression so a new keyword is introduced called typename
typename T::A* a6;
it instructs the compiler to treat the subsequent statement as a declaration.
Since the keyword was on the payroll,
heck, why not fix the confusion caused
by the original decision to reuse the
class keyword.
Thats why we have both
You can have a look at this post, it will definitely help you, I just extracted from it as much as I could
Consider the code
template<class T> somefunction( T * arg )
{
T::sometype x; // broken
.
.
Unfortunately, the compiler is not required to be psychic, and doesn't know whether T::sometype will end up referring to a type name or a static member of T. So, one uses typename to tell it:
template<class T> somefunction( T * arg )
{
typename T::sometype x; // works!
.
.
In some situations where you refer to a member of so called dependent type (meaning "dependent on template parameter"), the compiler cannot always unambiguously deduce the semantic meaning of the resultant construct, because it doesn't know what kind of name that is (i.e. whether it is a name of a type, a name of a data member or name of something else). In cases like that you have to disambiguate the situation by explicitly telling the compiler that the name belongs to a typename defined as a member of that dependent type.
For example
template <class T> struct S {
typename T::type i;
};
In this example the keyword typename in necessary for the code to compile.
The same thing happens when you want to refer to a template member of dependent type, i.e. to a name that designates a template. You also have to help the compiler by using the keyword template, although it is placed differently
template <class T> struct S {
T::template ptr<int> p;
};
In some cases it might be necessary to use both
template <class T> struct S {
typename T::template ptr<int>::type i;
};
(if I got the syntax correctly).
Of course, another role of the keyword typename is to be used in template parameter declarations.
The secret lies in the fact that a template can be specialized for some types. This means it also can define the interface completely different for several types. For example you can write:
template<typename T>
struct test {
typedef T* ptr;
};
template<> // complete specialization
struct test<int> { // for the case T is int
T* ptr;
};
One might ask why is this useful and indeed: That really looks useless. But take in mind that for example std::vector<bool> the reference type looks completely different than for other Ts. Admittedly it doesn't change the kind of reference from a type to something different but nevertheless it could happen.
Now what happens if you write your own templates using this test template. Something like this
template<typename T>
void print(T& x) {
test<T>::ptr p = &x;
std::cout << *p << std::endl;
}
it seems to be ok for you because you expect that test<T>::ptr is a type. But the compiler doesn't know and in deed he is even advised by the standard to expect the opposite, test<T>::ptr isn't a type. To tell the compiler what you expect you have to add a typename before. The correct template looks like this
template<typename T>
void print(T& x) {
typename test<T>::ptr p = &x;
std::cout << *p << std::endl;
}
Bottom line: You have to add typename before whenever you use a nested type of a template in your templates. (Of course only if a template parameter of your template is used for that inner template.)
Two uses:
As a template argument keyword (instead of class)
A typename keyword tells the compiler that an identifier is a type (rather than a static member variable)
template <typename T> class X // [1]
{
typename T::Y _member; // [2]
}
I think all of the answers have mentioned that the typename keyword, is used in two different cases:
a) When declaring a template type parameter. e.g.
template<class T> class MyClass{}; // these two cases are
template<typename T> class MyNewClass{}; // exactly the same.
Which there is no difference between them and they are EXACTLY the same.
b) Before using a nested dependent type name for a template.
template<class T>
void foo(const T & param)
{
typename T::NestedType * value; // we should use typename here
}
Which not using typename leads to parsing/compilation errors.
What I want to add to the second case, as mentioned in Scot Meyers book Effective C++, is that there is an exception of using typename before a nested dependant type name. The exception is that if you use the nested dependant type name either as a base class or in a member initialization list, you should not use typename there:
template<class T>
class D : public B<T>::NestedType // No need for typename here
{
public:
D(std::string str) : B<T>::NestedType(str) // No need for typename here
{
typename B<T>::AnotherNestedType * x; // typename is needed here
}
}
Note: Using typename for the second case (i.e. before nested dependent type name) is not needed since C++20.
#include <iostream>
class A {
public:
typedef int my_t;
};
template <class T>
class B {
public:
// T::my_t *ptr; // It will produce compilation error
typename T::my_t *ptr; // It will output 5
};
int main() {
B<A> b;
int my_int = 5;
b.ptr = &my_int;
std::cout << *b.ptr;
std::cin.ignore();
return 0;
}