3

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?

Jonathan Mee
  • 37,899
  • 23
  • 129
  • 288

2 Answers2

2

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>

Pablo Oliva
  • 334
  • 3
  • 12
1

It is necessary because pair<T, T> is a dependent name, meaning that it changes depending on how foo was initialized.

mrks
  • 8,033
  • 1
  • 33
  • 62
  • Your'e saying it's dependent because `pair` could also be a variable template? – StoryTeller - Unslander Monica Nov 13 '17 at 13:52
  • @StoryTeller: dependent names pre-date variable templates. The standard committee was concerned that a classicly-designed compiler wouldn't have type information when processing `pair PointType` and wouldn't be able to distinguish between a templated type (the correct answer) or the two statements `pair < T` and `T > PointType` (assuming `pair`, `T`, and `PointType` are all variables; don't forget about https://en.wikipedia.org/wiki/Comma_operator ). `typename` distinguishes between those two possibilities. – Max Lybbert Nov 13 '17 at 14:24
  • 1
    @MaxLybbert - Except the example in the very page this answer links, uses a dependent name as a type, **without the typename keyword**. – StoryTeller - Unslander Monica Nov 13 '17 at 14:25
  • In the late '90s, GCC could get the correct answer without `typename`, but then code that compiled for GCC wouldn't compile for Visual Studio. GCC took out the extension. Then Visual Studio added the ability to accept that kind of code. I really don't know where things stand today. – Max Lybbert Nov 13 '17 at 14:26
  • @MaxLybbert - The very code was valid C++03. What are you talking about? It still **has** to be correct. C++11 and C++14 were backwards compatible. – StoryTeller - Unslander Monica Nov 13 '17 at 14:28
  • I don't know why you believe the code was valid C++03 (it may have been, but I don't know your basis for the statement). What I'm talking about is illustrated at https://stackoverflow.com/questions/5683257/why-is-typename-not-needed-here-in-visual-studio-2008-2010 (also note https://gcc.gnu.org/bugzilla/show_bug.cgi?id=14258#c1 ). – Max Lybbert Nov 13 '17 at 14:40
  • 1
    @MaxLybbert Looks like the standard never officially requires compilers to wait till types used in a template are fully defined before implementation of a template. The only way to require that seems to be the use of `typename` as such this could be viewed as a "required `typename`" even though modern compilers all figure this out on their own. – Jonathan Mee Nov 13 '17 at 15:21