Has the C++ standard committee considered templated namespaces? - c++

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?

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.

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?
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`?

Related

c++ auto for type and nontype templates

In c++17 template <auto> allows to declare templates with arbitrary type parameters. Partially inspired by this question, it would be useful to have an extension of template <auto> that captures both type and nontype template parameters, and also allows for a variadic version of it.
Are there plans for such an extension in the next c++20 release? Is there some fundamental problem in having a syntax like template<auto... X>, with X any type or nontype template parameter?
Are there plans for such an extension in the next c++20 release?
No.
Is there some fundamental problem in having a syntax like template<auto... X>, with X any type or nontype template parameter?
It would be a totally new concept in the language - having a name refer to either a type or a value in the same place. So it'd come with all sorts of additional questions - and probably additional language features to check if X is a type or not.
The syntax likely cannot be template <auto... X> struct Y { }; since that syntax already has meaning and means a bunch of values and Y<int>{} is ill-formed.
There are definitely places where such a thing would be useful though. A proposal would just have to address these issues.
The big issue with trying to do something like that is grammar. Template parameters state up-front whether they are templates, types, or values, and the most important reason for this is grammatical.
C++ is a context-sensitive grammar. That means that you cannot know, just from a sequence of tokens, what a particular sequence of tokens means. For example, IDENTIFIER LEFT_PAREN RIGHT_PAREN SEMICOLON. What does that mean?
It could mean to call a function named by IDENTIFIER with no parameters. It could mean to default initialize a prvalue of a class named by IDENTIFIER. These are rather different things; you might conceptually see them as similar, but C++'s grammar does not.
Templates are not macros; they're not doing token pasting. There is some understanding that a piece of code in a template is supposed to mean a specific thing. And you can only do that if you at least know what kind of thing a template parameter is.
In order to retain this ability, these "omni template parameters" cannot be utilized until you actually know what they mean. So in order to create such a feature in C++, you would need to:
Create a new syntax to declare omni template parameters (auto isn't going to fly, as it already has a specific meaning).
Provide a syntax for determining what kind of thing an omni template parameter is.
Require the user to invoke that syntax before they can use such parameter names in most ways. This would typically be via some form of specialized if constexpr block, but pattern matching proposals represent an interesting alternative/additional way to handle them (since they can be expressions as well as statements). And expansion statements represent a possible way to access all of the omni parameters in a parameter pack.
I can't see how it would be useful that a template argument could be dynamically either a type or a value? The code statements that use types are very different to those that which use constant values introduced through the template argument.
The only way would be a big "if constexpr" which would make it pointless in my view.
Ok, having looked more closely at the referenced question, I guess there is room there for generically pass-through wrapping the various explicit base template implementations that use different parameter orderings. I still fail to see a huge benefit. The compiler errors when it goes wrong are going to be unfathomable, if nothing else!
I remember being told that overloading and templates were going to rid the world of the unfathomable error messages generated from macros. I have yet to see it!

Will specialization of function templates in std for program-defined types no longer be allowed in C++20?

Quote from cppreference.com:
Adding template specializations
It is allowed to add template specializations for any standard library |class (since C++20)| template to the namespace std only if the declaration depends on at least one program-defined type and the specialization satisfies all requirements for the original template, except where such specializations are prohibited.
Does it mean, that starting from C++20, adding specializations of function templates to the std namespace for user-defined types will be no longer allowed? If so, it implies that many pieces of existing code can break, doesn't it? (It seems to me to be kind-of a "radical" change.) Moreover, it will inject into such codes undefined behavior, which will not trigger compilations errors (warnings hopefully will).
As it stands now it definitly looks that way. Previously [namespace.std] contained
A program may add a template specialization for any standard library template to namespace std only if the declaration depends on a user-defined type and the specialization meets the standard library requirements for the original template and is not explicitly prohibited.
While the current draft states
Unless explicitly prohibited, a program may add a template specialization for any standard library class template to namespace std provided that (a) the added declaration depends on at least one program-defined type and (b) the specialization meets the standard library requirements for the original template.
emphasis mine
And it looks like the paper Thou Shalt Not Specialize std Function Templates! by Walter E. Brown is responsible for it. In it he details an number of reason why this should be changed such as:
Herb Sutter: “specializations don’t participate in overloading. [...] If you want to customize a function base template and want that
customization to participate in overload resolution (or, to always be
used in the case of exact match), make it a plain old function, not a
specialization. And, if you do provide overloads, avoid also providing
specializations.”
David Abrahams: “it’s wrong to use function template specialization [because] it interacts in bad ways with overloads. [...] For example,
if you specialize the regular std::swap for std::vector<mytype>&,
your specialization won’t get chosen over the standard’s vector
specific swap, because specializations aren’t considered during
overload resolution.”
Howard Hinnant: “this issue has been settled for a long time. . . . Disregard Dave’s expert opinion/answer in this area at your own
peril.”
Eric Niebler: “[because of] the decidedly wonky way C++ resolves function calls in templates. . . , [w]e make an unqualified call to
swap in order to find an overload that might be defined in [...]
associated namespaces[...] , and we do using std::swap so that, on
the off-chance that there is no such overload, we find the default
version defined in the std namespace.”
High Integrity C++ Coding Standard: “Overload resolution does not take into account explicit specializations of function templates. Only
after overload resolution has chosen a function template will any
explicit specializations be considered.”
Not really that radical. This change is based on this paper from Walter E. Brown. The paper goes into rationale rather deeply, but ultimately it boils down to this:
Specialization of function templates is rather poor as a customization point. Overloading and ADL are much better in that regard. There are other customization points discussed in the paper as well.
The standard library doesn't rely on this poor customization point too much already.
The wording change that's put into place actually permits adding entire declarations to namespace std (not just specializations) where it's explicitly permitted. So now there are better customization points.
Given #1 and #2, it's rather unlikely existing code will break. Or at least, not enough for this to be a major problem. Code that used auto and register also "broke" in the past, but that minuscule amount of C++ code didn't stop progress.

How does a parser for C++ differentiate between comparisons and template instantiations?

In C++, the symbols '<' and '>' are used for comparisons as well as for signifying a template argument. Thus, the code snippet
[...] Foo < Bar > [...]
might be interpreted as any of the following two ways:
An object of type Foo with template argument Bar
Compare Foo to Bar, then compare the result to whatever comes next
How does the parser for a C++ compiler efficiently decide between those two possibilities?
If Foo is known to be a template name (e.g. a template <...> Foo ... declaration is in scope, or the compiler sees a template Foo sequence), then Foo < Bar cannot be a comparison. It must be a beginning of a template instantiation (or whatever Foo < Bar > is called this week).
If Foo is not a template name, then Foo < Bar is a comparison.
In most cases it is known what Foo is, because identifiers generally have to be declared before use, so there's no problem to decide one way or the other. There's one exception though: parsing template code. If Foo<Bar> is inside a template, and the meaning of Foo depends on a template parameter, then it is not known whether Foo is a template or not. The language standard directs to treat it as a non-template unless preceded by the keyword template.
The parser might implement this by feeding context back to the lexer. The lexer recognizes Foo as different types of tokens, depending on the context provided by the parser.
The important point to remember is that C++ grammar is not context-free. I.e., when the parser sees Foo < Bar (in most cases) knows that Foo refers to a template definition (by looking it up in the symbol table), and thus < cannot be a comparison.
There are difficult cases, when you literally have to guide the parser. For example, suppose that are writing a class template with a template member function, which you want to specialize explicitly. You might have to use syntax like:
a->template foo<int>();
(in some cases; see Calling template function within template class for details)
Also, comparisons inside non-type template arguments must be surrounded by parentheses, i.e.:
foo<(A > B)>
not
foo<A > B>
Non-static data member initializers bring more fun: http://open-std.org/JTC1/SC22/WG21/docs/cwg_active.html#325
C and C++ parsers are "context sensitive", in other words, for a given token or lexeme, it is not guaranteed to be distinct and have only one meaning - it depends on the context within which the token is used.
So, the parser part of the compiler will know (by understanding "where in the source it is") that it is parsing some kind of type or some kind of comparison (This is NOT simple to know, which is why reading the source of competent C or C++ compiler is not entirely straight forward - there are lots of conditions and function calls checking "is this one of these, if so do this, else do something else").
The keyword template helps the compiler understand what is going on, but in most cases, the compiler simply knows because < doesn't make sense in the other aspect - and if it doesn't make sense in EITHER form, then it's an error, so then it's just a matter of trying to figure out what the programmer might have wanted - and this is one of the reasons that sometimes, a simple mistake such as a missing } or template can lead the entire parsing astray and result in hundreds or thousands of errors [although sane compilers stop after a reasonable number to not fill the entire universe with error messages]
Most of the answers here confuse determining the meaning of the symbol (what I call "name resolution") with parsing (defined narrowly as "can read the syntax of the program").
You can do these tasks separately..
What this means is that you can build a completely context-free parser for C++ (as my company, Semantic Designs does), and leave the issues of deciding what the meaning of the symbol is to a explicitly seperate following task.
Now, that task is driven by the possible syntax interpretations of the source code. In our parsers, these are captured as ambiguities in the parse.
What name resolution does is collect information about the declarations of names, and use that information to determine which of the ambiguous parses doesn't make sense, and simply drop those. What remains is a single valid parse, with a single valid interpretation.
The machinery to accomplish name resolution in practice is a big mess. But that's the C++ committee's fault, not the parser or name resolver. The ambiguity removal with our tool is actually done automatically, making that part actually pretty nice but if you don't look inside our tools you would not appreciate that, but we do because it means a small engineering team was able to build it.
See an example of resolution of template-vs-less than on C++s most vexing parse done by our parser.

Why is the 'Declare before use' rule not required inside a class? [duplicate]

This question already has answers here:
Do class functions/variables have to be declared before being used?
(5 answers)
Closed 4 years ago.
I'm wondering why the declare-before-use rule of C++ doesn't hold inside a class.
Look at this example:
#ifdef BASE
struct Base {
#endif
struct B;
struct A {
B *b;
A(){ b->foo(); }
};
struct B {
void foo() {}
};
#ifdef BASE
};
#endif
int main( ) { return 0; }
If BASE is defined, the code is valid.
Within A's constructor I can use B::foo, which hasn't been declared yet.
Why does this work and, mostly, why only works inside a class?
Well, to be pedantic there's no "declare before use rule" in C++. There are rules of name lookup, which are pretty complicated, but which can be (and often are) roughly simplified into the generic "declare before use rule" with a number of exceptions. (In a way, the situation is similar to "operator precedence and associativity" rules. While the language specification has no such concepts, we often use them in practice, even though they are not entirely accurate.)
This is actually one of those exceptions. Member function definitions in C++ are specifically and intentionally excluded from that "declare before use rule" in a sense that name lookup from the bodies of these members is performed as if they are defined after the class definition.
The language specification states that in 3.4.1/8 (and footnote 30), although it uses a different wording. It says that during the name lookup from the member function definition, the entire class definition is inspected, not just the portion above the member function definition. Footnote 30 additionally states though that the lookup rules are the same for functions defined inside the class definition or outside the class definition (which is pretty much what I said above).
Your example is a bit non-trivial. It raises the immediate question about member function definitions in nested classes: should they be interpreted as if they are defined after the definition of the most enclosing class? The answer is yes. 3.4.1/8 covers this situation as well.
"Design & Evolution of C++" book describes the reasoning behind these decisions.
That's because member functions are compiled only after the whole class definition has been parsed by the compiler, even when the function definition is written inline, whereas regular functions are compiled immediatedly after being read. The C++ standard requires this behaviour.
I don't know the chapter and verse of the standard on this.
But if you would apply the "declare before use" rule strictly within a class, you would not be able to declare member variables at the bottom of the class declaration either. You would have to declare them first, in order to use them e.g. in a constructor initialization list.
I could imagine the "declare before use" rule has been relaxed a bit within the class declaration to allow for "cleaner" overall layout.
Just guesswork, as I said.
The most stubborn problems in the definition of C++ relate to name lookup: exactly which uses of a name refer to which declarations? Here, I'll describe just one kind of lookup problem: the ones that relate to order dependencies between class member declarations. [...]
Difficulties arise because of conflicts between goals:
We want to be able to do syntax analysis reading the source text once only.
Reordering the members of a class should not change the meaning of the class.
A member function body explicitly written inline should mean the same thing when written out of line.
Names from an outer scope should be usable from an inner scope (in the same way as they are in C).
The rules for name lookup should be independent of what a name refers to.
If all of these hold, the language will be reasonably fast to parse, and users won't have to worry about these rules because the compiler will catch the ambiguous and near ambiguous cases. The current rules come very close to this ideal.
[The Design And Evolution Of C++, section 6.3.1 called Lookup Issues on page 138]

Why are structs not allowed in template definitions?

The following code yields an error error: ‘struct Foo’ is not a valid type for a template constant parameter:
template <struct Foo>
struct Bar {
};
Why is that so?
template <class Foo>
struct Bar {
};
works perfectly fine and even accepts an struct as argument.
This is just an artifact of the syntax rules - the syntax just lets you use the class or typename keywords to indicate a type template parameter. Otherwise the parameter has to be a 'non-type' template parameter (basically an integral, pointer or reference type).
I suppose Stroustrup (and whoever else he might have taken input from) decided that there was no need to include struct as a a keyword to indicate a type template parameter since there was no need for backwards compatibility with C.
In fact, my recollection (I'll have to do some book readin' when I get back home) is that when typename was added to indicate a template type parameter, Stroustrup would have liked to take away using the class keyword for that purpose (since it was confusing), but there was too much code that relied on it.
Edit:
Turns out the story is more like (from a blog entry by Stan Lippman):
The reason for the two keywords is
historical. In the original template
specification, Stroustrup reused the
existing class keyword to specify a
type parameter rather than introduce a
new keyword that might of course break
existing programs. It wasn't that a
new keyword wasn't considered -- just
that it wasn't considered necessary
given its potential disruption. And up
until the ISO-C++ standard, this was
the only way to declare a type
parameter.
Reuses of existing keywords seems to
always sow confusion. What we found is
that beginners were [wondering]
whether the use of the class
constrained or limited the type
arguments a user could specify to be
class types rather than, say, a
built-in or pointer type. So, there
was some feeling that not having
introduced a new keyword was a
mistake.
During standardization, certain
constructs were discovered within a
template definition that resolved to
expressions although they were meant
to indicate declarations
...
The committee decided that a new
keyword was just the ticket to get the
compiler off its unfortunate obsession
with expressions. The new keyword was
the self-describing typename.
...
Since the keyword was on the payroll,
heck, why not fix the confusion caused
by the original decision to reuse the
class keyword. Of course, given the
extensive body of existing code and
books and articles and talks and
postings using the class keyword, they
chose to also retain support for that
use of the keyword as well. So that's
why you have both.
You can instantiate a template using a struct; however, the syntax for declaring a template type only allows the keywords "class" or "typename" to appear where you are attempting to use the keyword "struct".
I should add that you can also use a specific type (e.g. int), if you want to instantiate your template based on a compile-time constant or based on an object with external linkage... but that's somewhat of an aside.
The short answer is: template <class Foo> even accepts a union or a double - still, neither is allowed instead of class. However, typename is. That's just the way the syntax was defined.
A somewhat longer answer: When templates for C++ where "invented", there was a keyword needed at that place saying that the next identifier would be a type name. It was decided to re-use the existing class keyword. That was a bit confusing, but there's a general reluctance to introducing more keywords, because they always break some existing code which used this as an identifier when it wasn't a keyword.
Later, typename became a keyword for other reasons, and since it is a much better fit, it can now be used in that place: template <typename Foo>. However, with billions of lines of code out there using class in that place, it must remain valid for that purpose. So now both are allowed.
As is common in C++, this created several camps as to what keyword to use in that place. Some stick with class, because they've been using it for more than a decade. Others prefer typename, because it's a much better fit. Some use class when Foo is expected to be of a class type (members are accessed) and typename when built-ins can be used, too.
Because the keyword for template parameters is class or typename. This doesn't restrict the Foo parameter to be a class - it can be of any type.