This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of New status.
source_location
is not specified when used in an default template argumentSection: 17.8.2.2 [support.srcloc.cons] Status: New Submitter: Cassio Neri Opened: 2025-02-07 Last modified: 2025-02-07
Priority: Not Prioritized
View all other issues in [support.srcloc.cons].
View all issues with New status.
Discussion:
17.8.2.2 [support.srcloc.cons]/2 in N5001 says nothing
about using source_location::current()
in an initializer of a template
parameter. The example below suggests that gcc, clang and msvc seem to agree
on this case. It would be nice if the Standard legitimized current practice.
#include <source_location>
template <int i = std::source_location::current().line()> // line 3
struct A {
static constexpr int value = i;
};
template <int i = std::source_location::current().line()> // line 8
constexpr int f() {
return i;
}
static_assert(A<>::value == 3); // passes
static_assert(f() == 8); // passes
[2025-02-07; Jonathan provides wording]
For a default argument of a function parameter, current()
is recommended
to return the location of the caller that makes use of that default argument.
For a default template argument, the location would be determined by the
template's point of instantiation (13.8.4.1 [temp.point]) which would
not always do what users expect. Using the location of the default template
argument in the template declaration seems sensible and predictable,
and matches existing practice. Arguably, this doesn't need to be stated
because it's just "exactly where the current()
call appear in the source".
The other cases in the Remarks paragraph are situations where the preferred
location is different, because we want to know where it's used, not defined.
Proposed resolution:
This wording is relative to N5001.
-2- Remarks: Any call tocurrent
that appears as a default member initializer (11.4 [class.mem]), or as a subexpression thereof, should correspond to the location of the constructor definition or aggregate initialization that uses the default member initializer. Any call tocurrent
that appears as a default argument (9.3.4.7 [dcl.fct.default]), or as a subexpression thereof, should correspond to the location of the invocation of the function that uses the default argument (7.6.1.3 [expr.call]). Any call tocurrent
that appears as a default template argument (13.2 [temp.param]), or as a subexpression thereof, should correspond to the location where the default template argument is specified.