-2

Namespaces are in many was like classes with no constructors, no destructors, no inheritance, final, and only static methods and members. After all, this kind of classes can essentially be used only the way namespaces are used: a named scope for declarations and definitions.

... except that the above is not true, since classes can be templated - and namespaces cannot. There have been a couple of questions here on the site similar to "can I template a namespace", but what I'd like to know is - has the C++ standard committee ever considered a proposal to make namespaces templatable? If it has, was the proposal rejected? If it was, what were the reasons?

einpoklum
  • 118,144
  • 57
  • 340
  • 684
  • 3
    Can you give a concise example where _templated namespaces_ would make sense please? – πάντα ῥεῖ Mar 14 '16 at 20:56
  • While it can sometimes be helpful, thinking of a namespace with a class with all static members is incorrect. There are several key differences there, which prevent this from being implemented. – SergeyA Mar 14 '16 at 20:57
  • @πάνταῥεῖ, I can give you one. For example, you have two different implementations of a certain feature, which are done through a set of free-standing functions. By having a templated namespace you could have those implementations separated. – SergeyA Mar 14 '16 at 21:00
  • 2
    No way, the complexity would be huge (Eg.: ADL Argument dependent lookup) –  Mar 14 '16 at 21:00
  • @πάνταῥεῖ: Maybe [something like this](http://pastebin.com/v9izgLD8) – einpoklum Mar 14 '16 at 21:16
  • @SergeyA: I did say "in many ways"... also, you could answer and say "nobody would propose this to the committee because XYZ so it doesn't make sense", that's a valid answer I suppose. – einpoklum Mar 14 '16 at 21:17
  • @DieterLücking: Why would the complexity be any more huge than with templated classes? – einpoklum Mar 14 '16 at 21:18
  • 1
    Well, there is at least one major difference between a namespace and classes you did not mention: A class has to be specified in one place, a namespace (and its content) can be specified in many chunks. – Rumburak Mar 14 '16 at 21:29
  • @Rumburak: Actually, with templates, classes are instantiated - which is sort of like a definition - in different places; also, classes can inherit, with superclasses defined elsewhere; finally, static members of templated classes are defined and initialized separately from the class. Still, you're right, that is a difference. I'm not saying namespaces = a kind of classes. – einpoklum Mar 14 '16 at 21:34
  • 2
    @SergeyA: "For example, you have two different implementations of a certain feature, which are done through a set of free-standing functions. By having a templated namespace you could have those implementations separated. " You could just use tag dispatch for this instead. It's not really a compelling usecase IMO – Chris Beck Mar 14 '16 at 23:36

2 Answers2

1

The inability to have a template namespace is actually just one way in which they differ from classes. Others would be things like new namespace, and sizeof (namespace) - how could a compiler implement that, given that a namespace may extend over many compilation units?

Looking just at template namespaces... While it can at times be hard to keep up with all the proposals for new C++ features, I don't recall ever seeing one that attempted to add a feature such as you describe.

Would it ever be considered, assuming someone were to write a proposal? As Stroustrup indicates in this interview (http://www.stroustrup.com/devXinterview.html):

For C++ to remain viable for decades to come, it is essential that Standard C++ isn't extended to support every academic and commercial fad. Most language facilities that people ask for can be adequately addressed through libraries using only current C++ facilities.

As you indicate yourself, what you are asking for is basically already there: just use a templated class with static members. This seems to disqualify it as a potential new feature, at least in the eyes of Stroustrup.

H. Guijt
  • 3,325
  • 11
  • 16
  • Nobody suggested namespaces are classes, just that it makes sense to want to be able to template them like you can classes, because of the use patterns. Note you cannot instantiate classes with no ctors... and it their sizeof() therefore does not matter. ... having said that - fair enough answer. – einpoklum Mar 14 '16 at 22:34
  • Just one minor correction: you most certainly _can_ instantiate a class that does not have a constructor. Just try instantiating `class A { int a; };` – H. Guijt Mar 15 '16 at 07:18
  • That class has a constructor, it's just implicit. If you delete the implicit ctors you won't be able to instantiate it (I think). – einpoklum Mar 15 '16 at 09:56
1

How would ADL work if namespaces can be templated? Are we supposed to create special template deduction rules for ADL then?

More importantly, can you justify the added complexity to the language by demonstrating a use-case that can't be filled by, just make a template struct with only static members? If a template namespace is just like a gimped template struct, that doesn't seem to be very compelling.


Also. I understand you weren't satisfied with the other questions about namespace / template hybrids, but one point in this answer seems to be relevant to your question:

Why can't namespaces be template parameters?

  1. Possibly difficult: A namespace isn't a complete, self-contained entity. Different members of a namespace can be declared in different headers and even different compilation units.

If a namespace is a template, how will this even work? Can you still "reopen" the namespace like you can with a regular namespace? If that's allowed, then what is the point of instantiation of the namespace?

It sounds like it could potentially be extremely complicated.


Also: Will the language still be easily parsable after your proposed feature?

One of the most vexing things in C++ is the need to write template often when defining templates that refer to other templates, in order to resolve ambiguity in the grammar regarding whether < is a less than operator or a template parameter list.

3.4.5 [basic.lookup.classref] In a class member access expression (5.2.5), if the . or -> token is immediately followed by an identifier followed by a <, the identifier must be looked up to determine whether the < is the beginning of a template argument list (14.2) or a less-than operator. The identifier is first looked up in the class of the object expression. If the identifier is not found, it is then looked up in the context of the entire postfix-expression and shall name a class template. If the lookup in the class of the object expression finds a template, the name is also looked up in the context of the entire postfix-expression and

— if the name is not found, the name found in the class of the object expression is used, otherwise

— if the name is found in the context of the entire postfix-expression and does not name a class template, the name found in the class of the object expression is used, otherwise

— if the name found is a class template, it shall refer to the same entity as the one found in the class of the object expression, otherwise the program is ill-formed.

If namespaces can be templates, don't we have to write template for them also, whenever you will refer to a template after a :: operator? For the same reason that foo::bar < 1 ... could be a namespace template bar inside of template foo with a non-type template parameter, or it could be a comparison of 1 with int foo::bar.

How do we disambiguate between that and the third possibility, foo is a namespace and bar is a regular class template inside of it`?

Community
  • 1
  • 1
Chris Beck
  • 15,614
  • 4
  • 51
  • 87
  • The answer to your questions are: 1. Like with classes with (no ctors and) no non-static members. 2. Yes; although a restriction on this would not be terrible. 3. The namespace is never really instantiated, rather its members are. So, again, like in classes with no static members. – einpoklum Mar 14 '16 at 23:44
  • In a class template, the class as a whole is instantiated at a specific point in the program, and it's members bound according to the definitions visible at that point in the program. This is pretty important and different from what you are saying, where the members are each instantiated at arbitrary points in time independently of one another. That would mean that template namespace is really more like, a simple namespace with many individual template functions defined within it. It means that if you write `foo` in one such function, it could bind to something completely different in another – Chris Beck Mar 14 '16 at 23:51
  • Your answer to 1 is not satisfactory. In ADL a class is never deduced, only a namespace is, and those cannot be templates. Suppose I have something like `template namespace serialization { ostream & operator << (ostream & , const T &); }`. If I write a `<<` expression using a member of an object which is a member of `serialization` say, and that member is an int, should be the compiler deduce that it should use an operator in `serialization`? Should you be able to write `using namespace template serialization;` and get all of the namespaces? – Chris Beck Mar 14 '16 at 23:57