tags:

views:

163

answers:

4

Reading C++ Templates: The Complete Guide and it says

Note that templates cannot be declared in a function

It does not give explanation and/or cross reference to any other chapter in the book or external resource.

Could someone help in explaining this. Probably it is explained later in the book but not there yet. If explained earlier, I must have missed it.

Example:

int main()
{
  class DummyClass  //  This compiles ok
  {
    int object;
  };

  template <typename T> //  compile error "expected primary-expression before "template""
  class DummyTemplate
  {
    T object;
  };

  return 0;
}

I do not understand the error message from gcc either. The error message says:

expected primary-expression before "template"
+7  A: 

It means you cannot do something like the following

  void foo()
  {
       template <typename T> //Error
       T something;
  }

Template declarations are only permitted at global, namespace, or class scope. :)

What is the reasoning behind it?

It is not allowed because the Standard says so .

ISO C++-98 (Section 14.2)

A *template declaration* can appear only as a namespace or class scope declaration

Does that make sense?

Prasoon Saurav
yes.Thanks. The question is why this is the case. What is the reasoning behind it?
MeThinks
`What is the reasoning behind it?`. I don't know much technicalities regarding implementation of template declaration inside a function but it is not allowed by the standard. **ISO C++ (14.2)** says `A *template declaration* can appear only as a namespace or class scope declaration`:)
Prasoon Saurav
+1. Thanks. Yes it makes sense. I see the standard does not allow it. It would help to understand why though. I have seen questions about what the standards does (not) allow answered with some explanations to back the standard. Very helpful for learners like me. This in no way takes away anything from this very good answer.
MeThinks
Well, I would be one to also deprecate the declaration of structs/functions from within a function. I have always found it messed up the code more than anything. Anyway I suppose this helps making the life of compiler-writer easier, and they have a hard enough job as it is not to require this kind of "feature" that doesn't bring much to the table.
Matthieu M.
Given that in C++ function local things are the same (generated code wise) as the same things at other scopes, I would expect that they would add almost no cost to the compiler.
BCS
+1  A: 

What exactly would be the use? So you can declare template variables that you can only use within the function? Is that really useful?

EJP
+1 for avoiding chaos code.
C Johnson
Yes. I can do this with structures and classes. Only one I can think of is function objects with respect to classes/structures to use with algorithms within a function. Not required but I do it to keep the classes/structures close to where I use them. Presumably I could have some reason but this is more of a learning exercise. The fact it may not be useful is a different discussion I guess.
MeThinks
Its usefulness is not really another discussion, IMO it is very pertinent to this one. If this were indeed allowed, how would you ever use it? The innards of a function are not visible to the caller, so how will you instantiate the template parameter with the appropriate type when calling this function?
Praetorian
@Preatirian. I hear you. However, I may not necessarily need to pass the template arguments. I may use the template multiple times, with different template arguments, in the function.I am just thinking loudly here to learn :)
MeThinks
@Praetorian Sorry for misspelling name
MeThinks
+1  A: 

The short answer to why this is, is because that how the guys who wrote the c/c++ compiler's and standards wanted it to be. Templates inside of functions must have been deemed to chaotic and or difficult to understand or parse, so they forbade it.

C Johnson
Thanks. Very understandable and can see that makes a lot of sense. Any references?
MeThinks
@MeThinks: See my comment to your comment.
Prasoon Saurav
A: 

The only time this would be useful would be if you created multiple instances of the template with different types withing the one function. Move your private classes out of your functions anyway. If that starts to clutter up your classes then they are too big and need to be refactored.

Cirdec
This is good advice.
MeThinks
Nevertheless I agree it's an odd inconsistency in the language. Like everyone else says, just chalk it down to: "because that's the way it is."
Cirdec