Title
using-declarations and default arguments
Status
cd6
Section
9.9 [namespace.udecl]
Submitter
Richard Smith

Created on 2014-03-30.00:00:00 last changed 28 months ago

Messages

Date: 2016-02-15.00:00:00

Notes from the February, 2016 meeting:

CWG determined that the case should be ill-formed, no diagnostic required, to allow implementations to continue to use either strategy.

Date: 2014-06-15.00:00:00

Notes from the June, 2014 meeting:

CWG was unable to come to consensus regarding the desired outcome, with an approximately equal split between desiring the first example to be well-formed or ill-formed. It was noted that the resolution of issue 1850 makes the corresponding case for non-dependent references ill-formed, with no diagnostic required. Similar questions also apply to completing an array type, which also involves a modification to an existing entity declaration in a given scope.

Date: 2020-11-15.00:00:00

[Accepted at the November, 2020 meeting as part of paper P1787R6 and moved to DR at the February, 2021 meeting.]

The status of an example like the following is not clear:

  void f(int, int);
  template<typename T> void g(T t) { f(t); }
  void f(int, int = 0);
  void h() { g(0); }

According to 13.8.4 [temp.dep.res] paragraph 1,

In resolving dependent names, names from the following sources are considered:

  • Declarations that are visible at the point of definition of the template.

  • ...

If this is to be interpreted as meaning that only the declarations that are visible at the point of definition can be used in overload resolution for dependent calls, the call g(0) is ill-formed. If, however, it is the names, not the declarations, that are captured, then presumably the second declaration of f should be considered, making the call well-formed. There is implementation divergence for this example.

The resolution of issue 1551 recently clarified the requirements in similar cases involving using-declarations:

  namespace N { void f(int, int); }
  using N::f;
  template<typename T> void g(T t) { f(t); }
  namespace N { void f(int, int = 0); }
  void h() { g(0); }

The note added to 9.9 [namespace.udecl] paragraph 11 makes clear that the call g(0) is well-formed in this example.

This outcome results in an unfortunate discrepancy between how default arguments and overloaded functions are treated, even though default arguments could conceptually be viewed as simply adding extra overloads for the additional arguments.

History
Date User Action Args
2022-08-19 07:54:33adminsetstatus: drwp -> cd6
2021-02-24 00:00:00adminsetstatus: accepted -> drwp
2020-12-15 00:00:00adminsetstatus: drafting -> accepted
2017-02-06 00:00:00adminsetmessages: + msg5755
2017-02-06 00:00:00adminsetstatus: open -> drafting
2014-07-07 00:00:00adminsetmessages: + msg5103
2014-03-30 00:00:00admincreate