5

Very often in C++ class definitions, especially in libraries, trait class etc., you see code similar to the following snippet:

template <typename Bar, typename Baz>
class Foo {
    using bar_type = Bar;
    using baz_type = Baz;
    // ... etc.
}

And only with these lines can you later refer to Foo<A,B>::bar_type or Foo<C,D>:baz_type. I'm wondering: Why doesn't the language standard require the compiler to automatically define types using the typename template parameters, i.e. allow removing the two using lines, and recognize Foo<A,B>::Bar as A and Foo<C,D>::Baz as D?

This should not even break existing code, since within Foo, the identifiers Bar and Baz are already taken anyway.

einpoklum
  • 118,144
  • 57
  • 340
  • 684
  • Because they might not be types. E.g., they might be a value, e.g., the N in `template struct array` – davidbak May 25 '16 at 22:23
  • 5
    They aren't always needed, and exposing them means client code may become coupled to them (assuming you meant those aliases to be public.) – juanchopanza May 25 '16 at 22:25
  • 1
    Another answer: Because it's trivial to do yourself. Which was the answer given when someone asked why isn't there a `super` keyword in C++ (but I don't have the reference to that at hand). – davidbak May 25 '16 at 22:26
  • @juanchopanza is right too, they're more like the names of parameters in a method decl than an actual defined value. – davidbak May 25 '16 at 22:26
  • @davidbak: "*Which was the answer given when someone asked why isn't there a super keyword in C++*" To be fair, that answer has more to do with multiple inheritance. In C++, there isn't necessarily a single `super` class instance. – Nicol Bolas May 25 '16 at 22:28
  • @NicolBolas - that too, but I distinctly remember an early C++ standards committee update in some magazine where it _was_ considered (the `super` keyword) by the committee until someone (forget who) said "just do `typedef xxx super`". – davidbak May 25 '16 at 22:29
  • 7
    The names aren't part of the template. `template struct X; template struct X; template struct X;` declares the same template three times. Just like for function parameters. – Kerrek SB May 25 '16 at 22:30
  • 1
    @NicolBolas - I actually found a reference right [here on SO](http://stackoverflow.com/a/180633/751579). – davidbak May 25 '16 at 22:31
  • @KerrekSB that's worthy of an answer. – Mark Ransom May 25 '16 at 22:39
  • @davidbak: 1. I said "typename" parameters. Let me edit and emphasize that. 2. for_each is trivial to implement, and yet we have ranged for loops; and the same argument goes for anything that's mostly syntactic sugar. – einpoklum May 25 '16 at 22:39
  • @juanchopanza: 1. They could be protected by default. 2. Whoever is using Foo knows A and B _anyway_... – einpoklum May 25 '16 at 22:41
  • @einpoklum 1. Same problem. 2. They don't know `A` as `Baz` or whatever. – juanchopanza May 25 '16 at 22:42
  • @KerrekSB: Make that an answer please. – einpoklum May 25 '16 at 22:46
  • @einpoklum: Done :-) – Kerrek SB May 25 '16 at 22:51
  • @juanchopanza [they do know if they're the same.](http://en.cppreference.com/w/cpp/types/is_same) – RamblingMad Jun 21 '16 at 01:53

1 Answers1

7

Parameter names aren't part of the entity that's being declared. This is true for both functions and templates. The following code only declares two separate entities:

extern void f(int, char, bool);
extern void f(int a, char b, bool c);
extern void f(int x, char b, bool z);

template <typename> struct X;
template <typename A> struct X;
template <typename T> struct X;

Note in particular that the following code is perfectly fine:

template <typename T> struct X { void f(); };   // X<T>::f not yet defined
template <typename U> void X<U>::f() {}         // now it's defined

All attempts at deriving additional structure from parameter names must deal with this situation. One of the most popular requests in this area are named function parameters; to date there has not been a satisfactory proposal for such an extension.

To some extent, all such proposals would require making the parameter names part of the declared entity. For functions, for example, that would raise the question whether parameter names would need to be mangled and exposed to the linker.

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • Who knows. One of the hidden implications of names of parameters becoming part of function signatures might be that it opens you up to companies like [Oracle](https://en.wikipedia.org/wiki/Oracle_America,_Inc._v._Google,_Inc.) suing your ass over it. – uh oh somebody needs a pupper May 25 '16 at 23:24
  • I'm repeatedly disheartened by people (not you obviously) who are somehow annoyed with questions regarding why the status quo is what it is, and downvote or vote to close with no comment - when there's a perfectly reasonable answer (which validates the rationale for the question.) – einpoklum May 25 '16 at 23:36
  • @einpoklum: I think this is a good question and I'm glad to have read the question and answer. However I have to admit that when I first read it, I was tempted to vote to close as not germane to stack overflow. The reason I guess is this line "Was this ever suggested? Discussed? Rejected?" I don't think that arbitrary historical inquiries into C++ make good SO questions -- the questions should be about programming, and ideally, of interest to a working programmer, rather than an academic or historian, IMO. Without that line, I probably up-vote it though. I'm only one sample point, YMMV. – Chris Beck May 25 '16 at 23:56
  • @ChrisBeck: 1. It's not necessarily a historical inquiry, because in some cases people say "oh, yes, this is a standing proposal to the standard committee" and then you can go read that and realize it might even make it to the next standard. 2. Some programmers write code by inspiration of the theoretical/academic discussion of the programming language. So these issues are of relevance to them. Different strokes for different folks etc. – einpoklum May 26 '16 at 09:42