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.

4100. Default arguments and signatures of standard library non-member functions

Section: 16.4.6.4 [global.functions] Status: New Submitter: Jiang An Opened: 2024-05-11 Last modified: 2024-08-02

Priority: 3

View all other issues in [global.functions].

View all issues with New status.

Discussion:

Currently, std::from_chars and std::to_chars are specified with default arguments. Some implementors want to split them into more overloads to determine the base 10 at compile time (LLVM issue #91268). However, the current standard wording doesn't clearly allow such technique.

[2024-08-02; Reflector poll]

Set priority to 3 after reflector poll. "It's a lot of new text just to say you can't do that, lose the example?" "Might be NAD, is this already disallowed?" "Only for member functions."

Proposed resolution:

This wording is relative to N4981.

  1. Modify 16.4.6.4 [global.functions] as indicated:

    […]

    -2- A call to a non-member function signature described in 17 [support] through 32 [thread] and D [depr] shall behave as if the implementation declared no additional non-member function signatures. However, for each non-member function specified with at least one default argument, an implementation may declare additional function signatures with one or more trailing parameters that have default arguments removed.

    [Example 1: The following program is possibly ill-formed because of ambiguity in overload resolution.

    #include <cstddef>
    #include <string>
    
    // One overload of std::stoi ([string.conversions]) is specified as
    // int stoi(const string& str, size_t* idx = nullptr, int base = 10);
    // An implementation can declare these overloads instead of using default arguments:
    // int stoi(const string& str, size_t* idx, int base);
    // int stoi(const string& str, size_t* idx);
    // int stoi(const string& str);
    
    namespace usr {
      int stoi(const std::string&);
      int stoi(const std::string&, std::size_t*);
    }
    
    int main() {
      using std::stoi;
      using usr::stoi;
      int (*p1)(const std::string&) = stoi;                 // possibly ill-formed
      int (*p2)(const std::string&, std::size_t*) = stoi;   // possibly ill-formed
    }
    

    — end example]