5

In C++, the concept of dependent names is important because:

Such names are unbound and are looked up at the point of the template instantiation ... in both the context of the template definition and the context of the point of instantiation

However, the only thing that the standard says is a dependent name is given in [temp.dep]/2, referring to unqualified function calls, basically in order to enable ADL to be fully effective for those function calls.

Are there any other dependent names besides those?

Consider some code like this, for example:

template <class T>
void foo(T t) {
    t.bar();
};

If one were to refer to bar as a "dependent name", would that be a technically incorrect use of the term, according to the standard?

curiousguy
  • 8,038
  • 2
  • 40
  • 58
Brian Bi
  • 111,498
  • 10
  • 176
  • 312
  • [temp.dep.expr]/3 "An *id-expression* is type-dependent if..." – M.M Feb 13 '20 at 21:31
  • @M.M I do not consider that to be sufficiently clear (*i.e.*, that a type-dependent id-expression is a dependent name). I also don't think any of the cases in that paragraph applies to the `t.bar()` example. – Brian Bi Feb 13 '20 at 21:32
  • [temp.dep]/2 also has *If an operand of an operator is a type-dependent expression, the operator also denotes a dependent name.* which should cover this case. – NathanOliver Feb 13 '20 at 21:37
  • @NathanOliver I don't think so. `bar` isn't an operator, is it? – Brian Bi Feb 13 '20 at 21:38
  • It is not, but `.` is. – NathanOliver Feb 13 '20 at 21:40
  • 1
    @NathanOliver We don't have `operator.` in C++ yet, so I'm a little bit skeptical that that applies. I don't think the `.` refers to any name at all. – Brian Bi Feb 13 '20 at 21:41
  • http://eel.is/c++draft/over.oper#3 suggests `.` is an operator, just one you can't overload. – N. Shead Feb 13 '20 at 21:55
  • @N.Shead I agree it is an operator, I just don't think it's associated with any name. – Brian Bi Feb 13 '20 at 21:56
  • [temp.dep.expr/5](https://eel.is/c++draft/temp.dep#expr-5) specifies member access expressions, but I'm not sure about the "unknown specialization" part. – Timo Feb 13 '20 at 22:24
  • 2
    @Timo `t.bar` certainly is a member of an unknown specialization, thus `t.bar` is a *type-dependent* expression. Are we meant to infer from this that `bar` is a *dependent name*? – Brian Bi Feb 13 '20 at 22:48
  • In https://stackoverflow.com/questions/610245/where-and-why-do-i-have-to-put-the-template-and-typename-keywords , I "complained" aswell, and noted `"Of all the constructs that denote dependent types or expressions, a subset of them represent names. Those names are therefore "dependent names"`. – Johannes Schaub - litb Feb 15 '20 at 15:18
  • 1
    Granted, it's very unclear, because a dependent type is an evaluation step further away from a dependent name. In fact, a name might often undergo name lookup and then it turns out it refers to a dependent type, like in `template struct A { typedef T type; A::type t; };` here, `A::type` is/refers-to a dependent type, but in order for this to be known, it necessarily is looked up in the template. So it cannot be a dependent name, afaics .. my C++ has become rusty :( – Johannes Schaub - litb Feb 15 '20 at 15:25
  • _Are we meant to infer from this that `bar` is a dependent name?_ No, do we need to? [There are special rules for dependent name resolution](https://timsong-cpp.github.io/cppwp/n4659/temp.dep.res#1) and it seems they are only make sense for free functions, not class member access. – Language Lawyer Jun 19 '20 at 09:31
  • BTW, http://wg21.link/p1787r4 removes the term "a member of an unknown specialization" and makes such names dependent. – Language Lawyer Jun 19 '20 at 11:38

1 Answers1

1

Thanks to Declarations and where to find them being accepted into C++23, there is now an explicit enumeration of categories of dependent names, which seems to cover the code in the question.

In N4919 [temp.dep.general]/2 it is stated that

[...] The component name of an unqualified-id (7.5.4.2) is dependent if

  • it is a conversion-function-id whose conversion-type-id is dependent, or
  • it is operator= and the current class is a templated entity, or
  • the unqualified-id is the postfix-expression in a dependent call.

And in [temp.dep.type]/5 the rules for when qualified names are dependent are given:

A qualified name (6.5.5) is dependent if

  • it is a conversion-function-id whose conversion-type-id is dependent, or
  • its lookup context is dependent and is not the current instantiation, or
  • its lookup context is the current instantiation and it is operator=, or
  • its lookup context is the current instantiation and has at least one dependent base class, and qualified name lookup for the name finds nothing (6.5.5).

Regarding the example of t.bar() given in the question, the name bar is described in the referenced section (6.5.5) ([basic.lookup.qual]) as a "member-qualified-name". Furthermore, [basic.lookup.qual]/2 explains that its "lookup context" is "the type of its associated object expression (considered dependent if the object expression is type-dependent)". Clearly t is type-dependent, and it is the lookup context for bar, so [temp.dep.type]/5.2 applies, and bar is indeed a dependent qualified name.

Brian Bi
  • 111,498
  • 10
  • 176
  • 312