28

I understand that namespaces cannot be template parameters. See the question, "template specialized on a namespace":

Given:

namespace A {
  class Foo;
  class Bar;
}

namespace B {
  class Foo;
  class Bar;
}

I want to template a class on the namespace A or B such that the following works:

template<name> class C {
  name::Foo* foo;
  name::Bar* bar;
};

I was wondering why this is the case. I understand that templates aren't structures, but is there a technical limitation to the compiler's design? Or is there some significant trade off for implementing this functionality?

Community
  • 1
  • 1
Alex
  • 6,843
  • 10
  • 52
  • 71

2 Answers2

28

Back when Bjarne Stroustrup first started talking about templates in C++ standards meetings he mentioned namespaces as template parameters. The reaction was skeptical, in part because namespaces themselves were so new, and we were afraid of combining two things that we didn't understand.

Pete Becker
  • 74,985
  • 8
  • 76
  • 165
  • 18
    @windfinder - I was one of the skeptics. – Pete Becker Oct 18 '12 at 13:03
  • 4
    You aren't exactly a secondary source, are ya?! ;-) – Alex Oct 18 '12 at 13:51
  • 1
    @PeteBecker any chance you remember around when that meeting was, or even better, have a link to some online conversation about it? I was having a discussion and wanted to link to the original source material if possible. – Catskul Sep 30 '19 at 16:32
  • 2
    @Catskul -- sorry, I can't really help. The first meeting of X3J16 was in 1990, and the discussions of future directions would have been in the first few meetings. – Pete Becker Sep 30 '19 at 19:14
15

This would be:

  1. (IMO) Inappropriate: Namespaces avoid name clashes. Polymorphism is outside their charter.
  2. Unnecessary: It would achieve nothing that can't already be done with structs.
  3. 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.
Marcelo Cantos
  • 181,030
  • 38
  • 327
  • 365
  • 10
    Polymorphism was outside of the charter of user-defined types until it was added to them. – Lightness Races in Orbit Oct 16 '12 at 00:44
  • 4
    I think you clinched it with item 3, though. Seems like that alone would make implementation intractible, and semantics nonsensical. – Lightness Races in Orbit Oct 16 '12 at 00:44
  • 1
    Adding to the *unnecessary*: you can always do `namespace A { struct types { typedef Foo Foo; typedef Bar Bar; }; }` and then use `A::types` as template argument. But I feel 1. is the most important reason (it was never designed for this use). Although 2. determines that there is little value to accept this as a new feature of the language. – David Rodríguez - dribeas Oct 16 '12 at 00:45
  • 1
    @LightnessRacesinOrbit: I agree that item 1 isn't a strong argument by itself, but it gains substantial weight when you factor in item 2. – Marcelo Cantos Oct 16 '12 at 00:46
  • I can understand arguments for 1 & 2, but I've always felt that if something makes sense it should be allowed (permissive with confines of the precepts), so I feel 2 is pretty weak. 3 is the real interesting question. I feel like this is easily implemented at compilation time, but might be impossible to implement at link time? – Alex Oct 16 '12 at 00:49
  • @windfinder: Did you mean that the other way around perchance? It might be possible at link time. – Lightness Races in Orbit Oct 16 '12 at 01:46
  • @SethCarnegie: Never going to happen. Stop dreaming! – Lightness Races in Orbit Oct 16 '12 at 01:47
  • 1. Namespace clash a lot the moment you start issuing `using namespace` commands. 2. Namespace were not necessary to begin with, you could use classes, after all - or prefixes, that works too... 3. I don't see where the difficult is; it would be glorified copy-paste, after all. It's true that if you use a namespace once with template parameters and once without you have a clash, but that's true for classes as well, essentially. – einpoklum Mar 14 '16 at 20:48
  • @einpoklum: They do not clash a lot. I liberally sprinkle my .cc files with "using namespace" declarations from several different libraries. They almost never cause collisions, and it's trivial to special-case the few that do. Namespaces also allow [argument-dependent name lookup](https://en.wikipedia.org/wiki/Argument-dependent_name_lookup), which structs don't (whether they could have is another matter, I guess). – Marcelo Cantos Mar 15 '16 at 01:17
  • @MarceloCantos, only if you don't believe into power of trivial macro expansion and if you think that partial (static) classes in C# are: 1. inappropriate, 2. useless. – Stepan Dyatkovskiy Mar 30 '19 at 10:11
  • I hate to nitpick, but your point (1) makes no sense. Regarding static polymorphism i.e. templates, namespaces and classes are the same. SP is not part of the charter for classes just like, as you say, it's not part of the charter for namespaces. A class doesn't care whether it's being used directly by name or through a template parameter or an alias, nor does/would a namespace. That's something from the template system itself. However, I agree with (2) and (3). – iPherian Dec 18 '19 at 10:17