Title
Insufficiently-defined behavior of std::function deduction guides
Status
new
Section
[func.wrap.func.con]
Submitter
Louis Dionne

Created on 2019-07-17.00:00:00, last changed 2019-07-28.15:43:50.

Messages

Date: 2019-08-05.18:00:24

Proposed resolution:

This wording is relative to N4820.

  1. Modify [func.wrap.func.con] as indicated:

    template<class F> function(F) -> function<see below>;
    

    -12- Remarks: This deduction guide participates in overload resolution only if &F::operator() is well-formed when treated as an unevaluated operand, and its type is of the form R(G::*)(A...) cv &opt noexceptopt for a class type G and a sequence of types A.... In that case, if decltype(&F::operator()) is of the form R(G::*)(A...) cv &opt noexceptopt for a class type G, then the deduced type is function<R(A...)>.

Date: 2019-07-17.00:00:00

The following code is currently undefined behavior:

#include <functional>

struct R { };
struct f0 { R operator()() && { return {}; } };

int main() { std::function f = f0{}; }

The reason is that [func.wrap.func.con]/12 says:

This deduction guide participates in overload resolution only if &F::operator() is well-formed when treated as an unevaluated operand. In that case, if decltype(&F::operator()) is of the form R(G::*)(A...) cv &opt noexceptopt for a class type G, then the deduced type is function<R(A...)>.

However, it does not define the behavior when &F::operator() is well-formed but not of the required form (in the above example it's of the form R(G::*)(A...) &&, which is rvalue-reference qualified instead of optionally-lvalue-reference qualified). libc++'s implementation of the deduction guide SFINAE's out when either &F::operator() is not well-formed, or it is not of the required form. It seems like mandating that behavior in the Standard is the way to go.

History
Date User Action Args
2019-07-28 15:43:50adminsetmessages: + msg10522
2019-07-17 00:00:00admincreate