What is the meaning of Note 1 in the C++ class member name lookup rules? - c++

From http://eel.is/c++draft/class.member.lookup#1 :
A search in a scope X for a name N from a program point P is a single search in X for N from P unless X is the scope of a class or class template T, in which case the following steps define the result of the search.
[Note 1: The result differs only if N is a conversion-function-id or if the single search would find nothing. — end note]
I'm having a hard time making a sense of the Note. It seems that a "single search" from a class scope will find preceding declarations at namespace scope, since the namespace scope contains the class scope. But, as we know, if the name has also been declared as a member of a non-dependent base class, then the base class member takes precedence over the namespace member. Note 1 seems to contradict this, since it's basically saying "if N is not a conversion-function-id, then you can just do a normal single search, and only if you fail to find anything, then use the procedure in this section". But the single search will succeed by finding the namespace scope declaration, and the class member lookup will yield a different result.
Where is the error in my understanding?

Answer
A single search considers only one scope—not an enclosing namespace or even a base class. It’s an unqualified search that considers all enclosing scopes. Single searches and (plain) searches are subroutines of these higher-level procedures.
Context
It should be said, since there have been a lot of these questions lately, that these terms exist to reduce ambiguity and imprecision (e.g., CWG issue 191) in the definitions of “programmer-level” constructs like (un)qualified name lookup. I didn’t invent them to increase the number of vocabulary words that the typical programmer should be expected to have memorized. (Put differently, the standard is not a tutorial.)
Of course, there’s nothing special about this particular question in this regard, but I must hope that this will thereby tend to find the people that need to see it.

The purpose of a "single search" is used to state how the lookup should perform for the member. In simple, if a single search is used to find the member in the namespace's scope, its enclosing scope will not be continue found due to the single search here, if there is no declaration yet found.
As the rule you quoted here, the scope of the class or class template is an exception here to the "single search", which means the single search should continue to be performed in its base classes if nothing yet found.
The declaration set is the result of a single search in the scope of C for N from immediately after the class-specifier of C if P is in a complete-class context of C or from P otherwise.
This is a recursive procedure. Hence, the note says "The result differs only if the single search would find nothing."
Whereas for "The result differs only if N is a conversion-function-id" because of the following rule:
In each case where conversion functions of a class S are considered for initializing an object or reference of type T, the candidate functions include the result of a search for the conversion-function-id operator T in S.
It does not mean the name "operator T" is the unique name to be lookup for the conversion function, the "permissible types" are also candidates to be found according to the relevant rule.
Each such case also defines sets of permissible types for explicit and non-explicit conversion functions;
Anyway, the note is used to say the exception for a "single search" which shouldn't have found any declaration by the single search but the other candidate ways would find them.

Related

what are lookup rules when a name occured before function's declarator-id?

#include <iostream>
typedef int Name;
Name func(int){
return 0;
}
int main(){
}
Consider the above code, I can't find a bullet in [basic.lookup.unqual] that can interpret how to lookup Name for definition of func. I will cite some potential rules here:
A name used in global scope, outside of any function, class or user-declared namespace, shall be declared before its use in global scope.
A name used in a user-declared namespace outside of the definition of any function or class shall be declared before its use in that namespace or before its use in a namespace enclosing its namespace.
In the definition of a function that is a member of namespace N, a name used after the function's declarator-id shall be declared before its use in the block in which it is used or in one of its enclosing blocks ([stmt.block]) or shall be declared before its use in namespace N or, if N is a nested namespace, shall be declared before its use in one of N's enclosing namespaces
Please note the emphasized parts, it seems that my case does not satisfy these bullets, because Function definitions have the form
function-definition:
attribute-specifier-seq(opt) decl-specifier-seq(opt) declarator virt-specifier-seq(opt) function-body
Let me analyze the first bullet. It says outside of any function,but according to the Function definitions rule, I think that Name is within the function(definition), bullet 1 isn't satisfied. Bullet 2 is similar with that of bullet 1. Bullet 3 says that the name used after the function's declarator-id, in my case, the Name is used before the function's declarator-id. So what's the rule about this case to find the unqualified name Name?
My confusions:
In my example ,the Name,func ,(int) and { return 0;}(function body) are all parts of that function definition,So:
what is outside of any function,such as the func in my example,where's area of outside of that function?
what is outside of the definition of any function,such as the func definition in my example,where's area of outside of the definition of that function?
I think that Name is within the function(definition), bullet 1 isn't satisfied.
Bullet 1 didn't say "function(definition)". It said "outside of any function". It doesn't specify declaration or definition; merely "outside of any function".
Since being inside or outside of a "function" is not a defined concept, it must be read as plain English. Is a function prototype "outside of the function"? Visually speaking, there's nothing special about a function prototype that is suggestive of an inside/outside distinction. By contrast, the function body's block scope does suggest an inside/outside distinction.
The intent of the text of course is quite obvious; it's talking about the function body. The rule equates "function", "class" and "namespace", all of which have a block that defines scoping for names. That is the most logical place for any inside/outside distinction, so it seems pretty obvious that it's saying that the global scope consists of everything that isn't in the scope of a function body, the scope of a class definition, or the scope of a namespace body.
So this can be easily handled with an editorial change.
Note that the committee recognizes the wording of this section (among others in that area) as somewhat defective, and there's a proposal for rewriting it into something more coherent in C++23. The new wording from the proposal completely rewrites this section.

What is the meaning of the last sentence in [basic.lookup]/1?

[basic.lookup]/1:
The name lookup rules apply uniformly to all names (including typedef-names (10.1.3), namespace-names
(10.3), and class-names (12.1)) wherever the grammar allows such names in the context discussed by a
particular rule. Name lookup associates the use of a name with a set of declarations (6.1) of that name. The
declarations found by name lookup shall either all declare the same entity or shall all declare functions; in the
latter case, the declarations are said to form a set of overloaded functions (16.1). Overload resolution (16.3)
takes place after name lookup has succeeded. The access rules (Clause 14) are considered only once name
lookup and function overload resolution (if applicable) have succeeded. Only after name lookup, function
overload resolution (if applicable) and access checking have succeeded are the attributes introduced by the
name’s declaration used further in expression processing (Clause 8).
What are those attributes introduced by the names´s declaration?
This sentence is visible in the N1638 - C++ Working Draft from April 2004, so it doesn't refer specifically to attributes of the form [[...]], which were introduced to the standard by N2761 - Towards support for attributes in C++
(Revision 6) in 2008.
[basic.lookup]/1
Only after name lookup, function overload resolution (if applicable) and access checking have succeeded are the attributes introduced by the name’s declaration used further in expression processing (clause 5).
Also [basic.def]/1
A declaration (clause 7) introduces names into a translation unit or redeclares names introduced by previous declarations. A declaration specifies the interpretation and attributes of these names.
From the above, and looking at the five other occurrences of 'attribute' in that paper, it appears to me that 'attribute' just means "information about the name". So in this case, things like extern, friend, the body of a function definition, and anything else you can say about a name in a declaration, that wasn't part of determining the interpretation of a name.
Since C++11 this would also include "generalised attributes" in the form [[..]]. There's a hint here, N2761 didn't introduce 'attributes', it just gave us a generalised syntax for them.
Function parameters, conversely, would not be 'attributes' in this sense, as the interpretation of the function name involves the parameters as part of overload resolution. The return type would be an attribute, since we don't look at it until we know what the name means, and which overload we've chosen.
In a slightly-more-standardese sense, I think you can say that the 'specifiers' are attributes, while the 'declarators' specify the interpretation of a name.
Pratically, I would say (without checking for a more-specific rule) that this is the rule that requires that deleted functions survive all the way through the lookup and name resolution process, and then fail the compilation.
Otherwise, a crafty compiler author might want to save their users some grief by eliminating deleted functions earlier, on the grounds that you can't call a deleted function, so why bother including it in the overload set?

Has the C++ standard committee considered templated namespaces?

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

Should name lookup be deferred for a dependent class/namespace-name in a class-member-access expression?

The following code is rejected by both clang and gcc
template<typename T>
void f(T t)
{
t.Dependent::f(); // clang accepts, gcc rejects
t.operator Dependent*(); // both reject
}
struct Dependent
{
void f();
};
struct A : Dependent
{
operator Dependent*();
};
template void f<A>(A);
My reading of the standard suggests both expressions should be accepted.
In both cases, Dependent can only be a type name.
In both cases, the name Dependent is to be "looked up in the class of the object expression" t. As t is a type-dependent expression, the lookup should be deferred until the template is instantiated.
Is there something I'm missing?
EDIT: If it is intended that such a name is not dependent, what is the rationale for this decision? I can see that it makes life easier for the implementor if they do not have to defer evaluation of a construct like t.operator X::Dependent* or t.X::Dependent::f where X could be either a namespace or a type name. I'm not clear on whether this is an intended or unintended side-effect of the current wording.
Relevant quotes from C++ Working Draft N3337:
3.4.5 Class member access [basic.lookup.classref]
If the id-expression in a class member access is a qualified-id of the form
class-name-or-namespace-name::...
the class-name-or-namespace-name following the . or -> operator is first looked up in the class of the
object expression and the name, if found, is used. Otherwise it is looked up in the context of the entire
postfix-expression. [ Note: See 3.4.3, which describes the lookup of a name before ::, which will only find a
type or namespace name. —end note ]
If the id-expression is a conversion-function-id, its conversion-type-id is first looked up in the class of the
object expression and the name, if found, is used. Otherwise it is looked up in the context of the entire
postfix-expression. In each of these lookups, only names that denote types or templates whose specializations
are types are considered.
14.6.2 Dependent names [temp.dep]
Inside a template, some constructs have semantics which may differ from one instantiation to another. Such a
construct depends on the template parameters. In particular, types and expressions may depend on the type
and/or value of template parameters (as determined by the template arguments) and this determines the
context for name lookup for certain names. Expressions may be type-dependent (on the type of a template
parameter) or value-dependent (on the value of a non-type template parameter).
[...]
Such names are unbound and are looked up at the point of the template instantiation (14.6.4.1) in both the
context of the template definition and the context of the point of instantiation.
14.6.2.1 Dependent types [temp.dep.type]
A name is a member of an unknown specialization if it is
[...]
— An id-expression denoting the member in a class member access expression (5.2.5) in which either
— the type of the object expression is the current instantiation, the current instantiation has at least
one dependent base class, and name lookup of the id-expression does not find a member of the
current instantiation or a non-dependent base class thereof; or
— the type of the object expression is dependent and is not the current instantiation.
[...]
A type is dependent if it is
— a member of an unknown specialization,
1
Here is how I think your first case, t.Dependent::f works. First, I believe (means, I am not totally sure) that 14.6.2.1p5 should say "unqualified-id" instead of "id-expression". But independent of that, your name Dependent::f is actually composed out of two names (in the Standard, each nested nested-name-specifier followed by a member name is called "qualified-id", even if grammatically, these are not qualified-id productions. So a name foo::bar::baz is a qualified-id but also contains 1 other "qualified-id" aswell).
Dependent and Dependent::f. The former is not "An id-expression denoting the member in a class member access expression", so you can't simply apply the rule that applies to Dependent::f to apply also to Dependent.
Dependent is therefor non-dependent and albeit it will need to be looked up within a dependent type will have to be found at definition time. I personally think that we should have a clause that says "When looking up a qualified-id where the qualifier is type-dependent, name lookup yields an empty result.", to handle these "force name-lookup to be done immediately" gracefully. So anyway, in the end, I think your first case is ill-formed by not finding Dependent (clause 3.4 can't just decide by itself over the head of clause 14 that the name is actually dependent anyway).
2
For your other case, operator Dependent, things are easier. You again have two names, Dependent and operator Dependent. Again, I found nothing that says that Dependent is a dependent name here (I am not sure whether that would be wrong or not. That's beyond me).
Name lookup comparison (say, the equality function of the name lookup hash table) for operator function names is "they are conversion-function-ids formed with the same type" (3.8). This means that in order to form the name itself (not yet doing name lookup!), you not only have to give the lexical spelling as is the case for identifiers, but you have to provide a type identity, which needs to be provided by Dependent.
That the lookup of the dependent id-expression in t.operator Dependent* is delayed simply means that the semantic type comparison is delayed. Try this one, which should work fine
struct Dependent; // forward decl at global scope
t.operator Dependent*(); // in function template
Your followup
If it is intended that such a name is not dependent, what is the rationale for this decision? I can see that it makes life easier for the implementor if they do not have to defer evaluation of a construct like t.operator X::Dependent* or t.X::Dependent::f where X could be either a namespace or a type name.
I don't know the rationale, but I think you already have given a good point. This looks very much to the rule that skips dependent base classes when looking up unqualified names. And I think what rationale applies for that case applies for this case aswell. It makes it easier to reason on the function template for the programmer, especially.
struct Dependent;
template<typename T>
void f(T t)
{
t.Dependent::f();
t.operator Dependent*();
}
The code looks fine, but if T happens to have a Dependent member, suddenly Dependent would have a different binding (because first we are told to look into t's class, and then into the surrounding scope). Under my current understanding of the templating rules, the above always refers to the surrounding scope's Dependent, so the above code is "safe", regarding to that pitfall.

List of C++ name resolution (and overloading) rules

Where I can find a list of the rules that a C++ compliant compiler must apply in order to perform names resolution (including overloading)?
I'd like something like a natural-language algorithm or flow chart.
C++ standard of course has this set of rules but it is build up as new language statements are introduced and the result it's pretty hard to remember.
To make a long story short, I'd like to know the complete and detailed answer to the question "What compiler do when it see the name 'A'?"
I know C++ is all "We do this when X but not Y if Z holds" so, I'm asking whether it is possible to make it more linear.
EDIT: I'm working on a draft of this topic, something that may be improved collectively once posted. However i'm very busy this days and it may take time to have something publicable. If someone interested i'll promote the "personal note on a raw txt file" to something better and post it.
Well, in broad strokes:
If the name is preceded by ::, as in ::A or X::A, then use qualified name lookup. First look up X, if it exists (if not use the global namespace) then look inside it for A. If X is a class, and A is not a direct member, then look in all the direct bases of X. If A is found in more than one base, fail.
Otherwise, if the name is used as a function call such as A( X ), use argument-dependent lookup. This is the hard part. Look for A in the namespace the type of X was declared in, in the friends of X, and if X is a template instantiation, likewise for all the arguments involved. Scopes associated only by typedef do not apply. Do this in addition to unqualified lookup.
Start with unqualified lookup if argument-dependent lookup doesn't apply. This is the usual way variables are found. Start at the current scope and work outwards until the name is found. Note that this respects using namespace directives, which the other two cases do not.
Simply glancing at the Standard will reveal many exceptions and gotchas. For example, unqualified lookup is used to determine whether the name is used as a function call, as opposed to a cast-expression, before ADL is used to generate a list of potential overloads. Unqualified lookup doesn't look for objects in enclosing scopes of nested of local classes, because such objects might not exist at the time of reference.
Apply common sense, and ask more specific questions when (as often it does) intuition fails.