Doc. no. | R0165??? |
Date: | Revised 2015-11-16 at 02:11:21 UTC |
Project: | Programming Language C++ |
Reply to: | Marshall Clow <lwgchair@gmail.com> |
Section: 26.8 [c.math] Status: Tentatively Ready Submitter: Daniel Krügler Opened: 2012-10-02 Last modified: 2015-11-04
Priority: 2
View other active issues in [c.math].
View all other issues in [c.math].
View all issues with Tentatively Ready status.
Discussion:
In C++03 the following two programs are invalid:
#include <cmath> int main() { std::abs(0u); }
#include <cstdlib> int main() { std::abs(0u); }
because none of the std::abs() overloads is a best match.
In C++11 the additional "sufficient overload" rule from 26.8 [c.math] p11 (see also LWG 2086) can be read to be applicable to the std::abs() overloads as well, which can lead to the following possible conclusions:
The program
#include <type_traits> #include <cmath> static_assert(std::is_same<decltype(std::abs(0u)), double>(), "Oops"); int main() { std::abs(0u); // Calls std::abs(double) }
is required to be well-formed, because of sub-bullet 2 ("[..] or an integer type [..]") of 26.8 [c.math] p11 (Note that the current resolution of LWG 2086 doesn't fix this problem).
Any translation unit including both <cmath> and <cstdlib> might be ill-formed because of two conflicting requirements for the return type of the overload std::abs(int).
It seems to me that at least the second outcome is not intended, personally I think that both are unfortunate: In contrast to all other floating-point functions explicitly listed in sub-clause 26.8 [c.math], the abs overloads have a special and well-defined meaning for signed integers and thus have explicit overloads returning a signed integral type. I also believe that there is no problem accepting that std::fabs(0u) is well-defined with return type double, because the leading 'f' clearly signals that we have a floating point function here. But the expected return type of std::abs(0u) seems less than clear to me. A very reasonable answer could be that this has the same type as its argument type, alternatively it could be a reasonably chosen signed integer type, or a floating point type. It should also be noted, that the corresponding "generic type function" rule set from C99/C1x in 7.25 p2+3 is restricted to the floating-point functions from <math.h> and <complex.h>, so cannot be applied to the abs functions (but to the fabs functions!).
Selecting a signed integer return type for unsigned input values can also problematic: The directly corresponding signed integer type would give half of the possible argument values an implementation-defined result value. Choosing the first signed integer value that can represent all positive values would solve this problem for unsigned int, but there would be no clear answer for the input type std::uintmax_t.Based on this it seems to me that the C++03 state in regard to unsigned integer values was the better situation, alerting the user that this code is ambigious at the moment (This might be change with different core-language rules as described in N3387).
[2013-04-20, Bristol]
Resolution: leave as new and bring it back in Chicago.
[2013-09 Chicago]
This issue also relates to LWG 2294
STL: these two issues should be bundled Stefanus: do what Pete says, and add overloads for unsigned to return directly STL: agree Consensus that this is an issue Walter: motion to move to Open STL: no wording for 2294 Stefanus: move to open and note the 2 issues are related and should be moved together Stefanus: add and define unsigned versions of abs()[2014-02-03 Howard comments]
Defining abs() for unsigned integers is a bad idea. Doing so would turn compile time errors into run time errors, especially in C++ where we have templates, and the types involved are not always apparent to the programmer at design time. For example, consider:
template <class Int>
Int
analyze(Int x, Int y)
{
// ...
if (std::abs(x - y) < threshold)
{
// ...
}
// ...
}
std::abs(expr) is often used to ask: Are these two numbers sufficiently close? When the assumption is that the two numbers are signed (either signed integral, or floating point), the logic is sound. But when the same logic is accidentally used with an arithmetic type not capable of representing negative numbers, and especially if unsigned overflow will silently happen, then the logic is no longer correct:
auto i = analyze(20u, 21u); // Today a compile time error // But with abs(unsigned) becomes a run time error
This is not idle speculation. Search the net for "abs unsigned" here or here.
In C++11, chrono durations and time_points are allowed to be based on unsigned integers. Taking the absolute value of the difference of two such time_points would be easy to accidentally do (say in code templated on time_points), and would certainly be a logic bug, caught at compile time unless we provide the error prone abs(unsigned).[2015-02, Cologne]
GR: Do we want to make the changes to both <cmath> and <cstdlib>?
AM: I think so; we should provide consistent overloads.
GR: Then we're imposing restrictions on what users put in the global namespace.
AM: I'm not so worried about that. Users already know not to use C library names.
VV: So what are we going to do about unsigned integers? AM: We will say that they are ill-formed.
AM: Does anyone volunteer to send updated wording to Daniel? GR, can you do it? GR: Sure.
GR: To clarify: we want to make unsigned types ill-formed?
AM: With promotion rank at least unsigned int.
GR: And NL suggests to just list those types.
This wording is relative to N3376.
Change 26.8 [c.math] p11 as indicated:
-11- Moreover, except for the abs functions, there shall be additional overloads sufficient to ensure:
[…]
[2015-03-03, Geoffrey Romer provides improved wording]
In the following I've drafted combined wording to resolve LWG 2192 and 2294. Note that the first two paragraphs are taken verbatim from the P/R of LWG 2294, but the third is newly drafted:
[2015-05-05 Lenexa: Howard to draft updated wording]
[2015-09-11: Howard updated wording]
[2015-10, Kona Saturday afternoon]
HH: abs() for unsigned types is really dangerous. People often use abs(x - y), which would be a disaster.
TK: That's why you need a two-argument abs_diff(x, y), especially for unsigned types.
JW: Lawrence has a proposal for abs_diff in the mailing.
STL: As an alternative to considering promotions, I would just ban all unsigned types, even unsigned char.
STL: Does the PR change any implementation? Is the final paragraph just a consequence?
HH: It's a consequence. It could just be a note.
VV: Ship it as is.
STL: Editorial: capitalize the first letter in the Note.
Move to Tentatively ready.
Proposed resolution:
This wording is relative to N4527.
Insert the following new paragraphs after 26.8 [c.math] p7:
-6- In addition to the int versions of certain math functions in <cstdlib>, C++ adds long and long long overloaded versions of these functions, with the same semantics.
-7- The added signatures are:long abs(long); // labs() long long abs(long long); // llabs() ldiv_t div(long, long); // ldiv() lldiv_t div(long long, long long); // lldiv()-?- To avoid ambiguities, C++ also adds the following overloads of abs() to <cstdlib>, with the semantics defined in <cmath>:
float abs(float); double abs(double); long double abs(long double);-?- To avoid ambiguities, C++ also adds the following overloads of abs() to <cmath>, with the semantics defined in <cstdlib>:
int abs(int); long abs(long); long long abs(long long);-?- If abs() is called with an argument of type X for which is_unsigned<X>::value is true and if X cannot be converted to int by integral promotion (4.5 [conv.prom]), the program is ill-formed. [Note: arguments that can be promoted to int are permitted for compatibility with C. — end note]
Section: X [dynarray.overview] Status: Ready Submitter: Jonathan Wakely Opened: 2013-04-23 Last modified: 2015-04-08
Priority: 0
View all issues with Ready status.
Discussion:
Addresses: arrays.ts
X [dynarray.overview] p2 says:
"Unless otherwise specified, all dynarray operations have the same requirements and semantics as specified in 23.2 [container.requirements]."
Some differences from 23.2 [container.requirements] are not explicitly specified, including at least the lack of a default constructor, copy assignment and swap member.
The wording could be similar to 23.3.2.1 [array.overview] which says "An array satisfies all of the requirements of a container and of a reversible container (23.2 [container.requirements]), except that a default constructed array object is not empty and that swap does not have constant complexity."[2013-09 Chicago:]
Move to Deferred. This feature will ship after C++14 and should be revisited then.
[2014-06-06 pre-Rapperswil]
This issue has been reopened as arrays-ts.
[2014-06-16 Rapperswil]
Move to Ready
[2014/11 Urbana]
Held at Ready status, pending clarification of Arrays TS
Proposed resolution:
Add to X [dynarray.overview] p2:
-2- A dynarray satisfies all of the requirements of a container and of a reversible container (23.2 [container.requirements]), except for default construction, assignment and swap. Unless otherwise specified, all dynarray operations have the same requirements and semantics as specified in 23.2 [container.requirements].
Section: X [dynarray.cons] Status: Ready Submitter: Jonathan Wakely Opened: 2013-04-23 Last modified: 2015-04-08
Priority: 0
View all issues with Ready status.
Discussion:
Addresses: arrays.ts
These constructors can interact badly::
template<class Alloc> dynarray(size_type c, const Alloc& alloc); dynarray(size_type c, const T& v);
Unless the second argument is a value of exactly the type T you will get the first constructor, i.e. all of these will fail to compile:
dynarray<long> dlong(1, 1); // 1 is not long dynarray<float> dflt(1, 1.0); // 1.0 is not float dynarray<int*> dptr(1, nullptr); // nullptr is not int* dynarray<void*> doh(1, 0); // 0 is not void*
The nullptr case is particularly annoying, a user trying to do the right thing by saying nullptr instead of NULL still gets the wrong result.
The constructor taking an allocator requires that "Alloc shall meet the requirements for an Allocator" but doesn't actually say "shall not participate in overload resolution unless ..." I believe we have no precedent for using SFINAE to check "the requirements for an Allocator" because it's a pretty complicated set of requirements. We could say it shall not participate in overload resolution if Alloc is implicitly convertible to value_type. Alternatively, we could follow the same approach used by other types that can be constructed with an unconstrained allocator type and use std::allocator_arg_t as the first argument instead of adding an allocator after the other arguments.[2013-09 Chicago:]
Move to Deferred. This feature will ship after C++14 and should be revisited then.
[2014-06-06 pre-Rapperswil]
This issue has been reopened as arrays-ts.
[2014-06-16 Rapperswil]
Move to Ready for alternative A
Previous resolution [SUPERSEDED]:
Either use the correct way to unambiguously call a constructor taking any type of allocator, i.e. change the constructors to take dynarray(std::allocator_arg_t, const Alloc&, ...) by modifying both the synopsis X [dynarray.overview] p2 and X [dynarray.cons] before p9 like so:
template <class Alloc> dynarray(allocator_arg_t, const Alloc& a, size_type c, const Alloc& alloc); template <class Alloc> dynarray(allocator_arg_t, const Alloc& a, size_type c, const T& v, const Alloc& alloc); template <class Alloc> dynarray(allocator_arg_t, const Alloc& a, const dynarray& d, const Alloc& alloc); template <class Alloc> dynarray(allocator_arg_t, const Alloc& a, initializer_list<T>, const Alloc& alloc);or constrain the problematic constructor by adding a new paragraph to X [dynarray.cons]:
template <class Alloc> dynarray(size_type c, const Alloc& alloc); template <class Alloc> dynarray(size_type c, const T& v, const Alloc& alloc); template <class Alloc> dynarray(const dynarray& d, const Alloc& alloc); template <class Alloc> dynarray(initializer_list<T>, const Alloc& alloc);-9- Requires: Alloc shall meet the requirements for an Allocator (17.6.3.5 [allocator.requirements]).
-10- Effects: Equivalent to the preceding constructors except that each element is constructed with uses-allocator construction (20.7.7.2 [allocator.uses.construction]). -?- Remarks: The first constructor shall not participate in overload resolution unless Alloc is not implicitly convertible to T.
[2014/11 Urbana]
Held at Ready status, pending clarification of Arrays TS
Proposed resolution:
Use the correct way to unambiguously call a constructor taking any type of allocator, i.e. change the constructors to take dynarray(std::allocator_arg_t, const Alloc&, ...) by modifying both the synopsis X [dynarray.overview] p2 and X [dynarray.cons] before p9 like so:
template <class Alloc> dynarray(allocator_arg_t, const Alloc& a, size_type c, const Alloc& alloc); template <class Alloc> dynarray(allocator_arg_t, const Alloc& a, size_type c, const T& v, const Alloc& alloc); template <class Alloc> dynarray(allocator_arg_t, const Alloc& a, const dynarray& d, const Alloc& alloc); template <class Alloc> dynarray(allocator_arg_t, const Alloc& a, initializer_list<T>, const Alloc& alloc);
Section: 30.6 [futures] Status: Ready Submitter: Jonathan Wakely Opened: 2013-07-30 Last modified: 2015-11-04
Priority: Not Prioritized
View all other issues in [futures].
View all issues with Ready status.
Discussion:
The standard does not specify the behaviour of this program:
#include <future> #include <cassert> struct NonTrivial { NonTrivial() : init(true) { } ~NonTrivial() { assert(init); } bool init; }; int main() { std::promise<NonTrivial> p; auto f = p.get_future(); p.set_exception(std::exception_ptr()); f.get(); }
The standard doesn't forbid making the state ready with a null exception_ptr, so what should get() return? There's no stored exception to throw, but it can't return a value because none was initialized.
A careful reading of the standard shows 30.6.4 [futures.state] p8 says "A shared state is ready only if it holds a value or an exception ready for retrieval." One can infer from the fact that set_exception() makes the state ready that it must store a value or exception, so cannot store "nothing", but that isn't explicit. The promise::set_exception() and promise::set_exception_at_thread_exit() members should require p != nullptr or should state the type of exception thrown if p is null.[2015-02 Cologne]
Handed over to SG1.
[2015-05 Lenexa, SG1 response]
SG1 provides P/R and requests move to SG1-OK status: Add Requires clauses for promise (30.6.5 [futures.promise]) set_exception (before p18) and set_exception_at_thread_exit (before p24): Requires: p is not null.
[2015-10, Kona issue prioritization]
Priority 0, move to Ready
Proposed resolution:
This wording is relative to N4431.
Add Requires clauses for promise (30.6.5 [futures.promise]) set_exception (before p18) and set_exception_at_thread_exit (before p24): Requires: p is not null.Change 30.6.5 [futures.promise] as depicted:
void set_exception(exception_ptr p);-??- Requires: p is not null.
-18- Effects: atomically stores the exception pointer p in the shared state and makes that state ready (30.6.4).
void set_exception_at_thread_exit(exception_ptr p);-??- Requires: p is not null.
-24- Effects: Stores the exception pointer p in the shared state without making that state ready immediately. […]
Section: 20.9.6 [comparisons] Status: Tentatively Ready Submitter: Joaquín M López Muñoz Opened: 2014-10-30 Last modified: 2015-11-04
Priority: 2
View other active issues in [comparisons].
View all other issues in [comparisons].
View all issues with Tentatively Ready status.
Discussion:
less<void>::operator(t, u) (and the same applies to the rest of void specializations for standard comparison function objects) returns t < u even if t and u are pointers, which by 5.9 [expr.rel]/3 is undefined except if both pointers point to the same array or object. This might be regarded as a specification defect since the intention of N3421 is that less<> can substitute for less<T> in any case where the latter is applicable. less<void> can be rewritten in the following manner to cope with pointers:
template<> struct less<void> { typedef unspecified is_transparent; template <class T, class U> struct pointer_overload : std::is_pointer<std::common_type_t<T, U>> {}; template < class T, class U, typename std::enable_if<!pointer_overload<T, U>::value>::type* = nullptr > auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) < std::forward<U>(u)) { return std::forward<T>(t) < std::forward<U>(u); } template < class T, class U, typename std::enable_if<pointer_overload<T, U>::value>::type* = nullptr > auto operator()(T&& t, U&& u) const -> decltype(std::declval<std::less<std::common_type_t<T, U>>>()(std::forward<T>(t), std::forward<U>(u))) { std::less<std::common_type_t<T, U>> l; return l(std::forward<T>(t), std::forward<U>(u)); } };
This wording is relative to N4140.
Change 20.9.6 [comparisons] p14 as indicated:
-14- For templates greater, less, greater_equal, and less_equal, the specializations for any pointer type yield a total order, even if the built-in operators <, >, <=, >= do not. For template specializations greater<void>, less<void>, greater_equal<void>, and less_equal<void>, the call operator with arguments whose common type CT is a pointer yields the same value as the corresponding comparison function object class specialization for CT.
[2015-02, Cologne]
AM: Is there any way this will be resolved elsewhere? VV: No. AM: Then we should bite the bullet and deal with it here.
MC: These diamond operators are already ugly. Making them more ugly isn't a big problem. JY found some issue with types that are convertible, and will reword. Jeffrey suggests improved wording.[2015-05, Lenexa]
STL: when diamond functions designed, this was on purpose
STL: this does go against the original design
STL: library is smarter and can give a total order
MC: given that the original design rejected this, give back to LEWG
STL: original proposal did not talk about total order
STL: don't feel strongly about changing the design
STL: no objections to taking this issue with some wording changes if people want it
MC: not happy with wording, comparing pointers — what does that mean?
STL: needs careful attention to wording
STL: want to guarantee that nullptr participates in total ordering
STL: all hooks into composite pointer type
MC: move from new to open with better wording
STL: to check updates to issue after Lenexa
[2015-06, Telecom]
MC: STL on the hook to update. He's shipping something today so not here.
MC: also add link to N4229
[2015-10, Kona Saturday afternoon]
STL was on the hook for wording, but STL: I don't care. The architecture on which this is an issue does not exist.
STL: We will also need to incorporate nullptr. TK: I think that's implied, since the wording is in terms of the resulting operation, not the deduced types.
STL: Seems legit. MC: I guess I'm OK with this. TK: I'm weakly in favour, so that we can get people to use transparent comparators without worrying.
STL: There's no change to implementations.
Move to Tentatively ready.
Proposed resolution:
This wording is relative to N4296.
Change 20.9.6 [comparisons] p14 as indicated:
-14- For templates greater, less, greater_equal, and less_equal, the specializations for any pointer type yield a total order, even if the built-in operators <, >, <=, >= do not. For template specializations greater<void>, less<void>, greater_equal<void>, and less_equal<void>, if the call operator calls a built-in operator comparing pointers, the call operator yields a total order.
Section: 20.8.1.3.1 [unique.ptr.runtime.ctor] Status: Tentatively Ready Submitter: Ville Voutilainen Opened: 2015-07-19 Last modified: 2015-11-04
Priority: 2
View all issues with Tentatively Ready status.
Discussion:
According to the wording in 20.8.1.3.1 [unique.ptr.runtime.ctor]/1, this won't work:
unique_ptr<int[], DeleterType> x{nullptr, DeleterType{}};
U is not the same type as pointer, so the first bullet will not do.
U is not a pointer type, so the second bullet will not do.
U is the same type as pointer, or
U is nullptr_t, or
pointer is the same type as element_type*, […]
[2015-10, Kona Saturday afternoon]
MC: Is it the right fix?
GR: It'd be awefully surprising if we had an interface that accepts null pointer values but not std::nullptr_t. I think the PR is good.
STL: Are any of the assignments and reset affected? [No, they don't operate on explicit {pointer, deleter} pairs.]
VV: This is already shipping, has been implemented, has been tested and works fine.
Move to Tentatively ready.
Proposed resolution:
This wording is relative to N4527.
Change 20.8.1.3.1 [unique.ptr.runtime.ctor] as indicated:
template <class U> explicit unique_ptr(U p) noexcept; template <class U> unique_ptr(U p, see below d) noexcept; template <class U> unique_ptr(U p, see below d) noexcept;-1- These constructors behave the same as the constructors that take a pointer parameter in the primary template except that they shall not participate in overload resolution unless either
U is the same type as pointer, or
U is nullptr_t, or
pointer is the same type as element_type*, U is a pointer type V*, and V(*)[] is convertible to element_type(*)[].
Section: X [memory.resource.global] Status: Tentatively Ready Submitter: Tim Song Opened: 2015-07-28 Last modified: 2015-11-04
Priority: 2
View all issues with Tentatively Ready status.
Discussion:
Addresses: fund.ts.v2
[memory.resource.global]/p7-8 says that the effects of set_default_resource(r) are
If r is non-null, sets the value of the default memory resource pointer to r, otherwise sets the default memory resource pointer to new_delete_resource().
and the operation has the postcondition
get_default_resource() == r.
When r is null, however, the postcondition cannot be met, since the call sets the default memory resource pointer to new_delete_resource(), and so get_default_resource() would return the value of new_delete_resource(), which is obviously not null and so cannot compare equal to r.
Previous resolution from Tim Song [SUPERSEDED]:This wording is relative to N4480.
Edit [memory.resource.global]/p8 as follows:
-6- memory_resource* set_default_resource(memory_resource* r) noexcept;-7- Effects: If r is non-null, sets the value of the default memory resource pointer to r, otherwise sets the default memory resource pointer to new_delete_resource().
-8- Postconditions: get_default_resource() == r if r is non-null; otherwise, get_default_resource() == new_delete_resource(). […]
[2015-09-15 Geoffrey Romer comments and suggests alternative wording]
Let's just strike X [memory.resource.global]/p8. The problem is that p8 is restating p7 incorrectly, but the solution is not to restate p7 correctly, it's to stop trying to restate p7 at all.
[2015-10, Kona Saturday afternoon]
Move to Tentatively ready
[2015-10-26]
Daniel adjusts wording to lib. fund. v2.
Proposed resolution:
This wording is relative to N4529.
Edit [memory.resource.global]/p8 as follows:
-6- memory_resource* set_default_resource(memory_resource* r) noexcept;-7- Effects: If r is non-null, sets the value of the default memory resource pointer to r, otherwise sets the default memory resource pointer to new_delete_resource().
-8- Postconditions: get_default_resource() == r.[…]
Section: 30.6.5 [futures.promise] Status: Ready Submitter: Tim Song Opened: 2015-07-31 Last modified: 2015-11-04
Priority: 0
View other active issues in [futures.promise].
View all other issues in [futures.promise].
View all issues with Ready status.
Discussion:
In 30.6.5 [futures.promise], the class synopsis shows
void set_value_at_thread_exit(const R& r); void set_value_at_thread_exit(see below);
There's no apparent reason for having void set_value_at_thread_exit(const R& r);, especially as that signature isn't really present in the specializations (particularly promise<void>). Note that the similar set_value only has a void set_value(see below);
While we are here, 30.6.5 [futures.promise]/p1 says that the specializations "differ only in the argument type of the member function set_value", which missed set_value_at_thread_exit.
[2015-10, Kona issue prioritization]
Priority 0, move to Ready
Proposed resolution:
This wording is relative to N4527.
Edit 30.6.5 [futures.promise], class template promise synopsis, as indicated:
namespace std { template <class R> class promise { public: […] // setting the result void set_value(see below); void set_exception(exception_ptr p); // setting the result with deferred notificationvoid set_value_at_thread_exit(const R& r);void set_value_at_thread_exit(see below); void set_exception_at_thread_exit(exception_ptr p); }; }
Edit 30.6.5 [futures.promise]/1 as indicated:
-1- The implementation shall provide the template promise and two specializations, promise<R&> and promise<void>. These differ only in the argument type of the member functions set_value and set_value_at_thread_exit, as set out in
its descriptiontheir descriptions, below.
priority_queue
taking allocators should call make_heap
Section: 23.6.5.2 [priqueue.cons.alloc] Status: Ready Submitter: Eric Schmidt Opened: 2015-09-19 Last modified: 2015-11-04
Priority: 0
View all issues with Ready status.
Discussion:
priority_queue
constructors taking both Container
and Alloc
arguments should
finish by calling make_heap
, just as with the constructors that do not have allocator parameters.
[2015-10, Kona issue prioritization]
Priority 0, move to Ready
Proposed resolution:
This wording is relative to N4527.
Change 23.6.5.2 [priqueue.cons.alloc] as indicated:
template <class Alloc> priority_queue(const Compare& compare, const Container& cont, const Alloc& a);-4- Effects: Initializes c with cont as the first argument and a as the second argument, and initializes comp with compare; calls
make_heap(c.begin(), c.end(), comp)
.template <class Alloc> priority_queue(const Compare& compare, Container&& cont, const Alloc& a);-5- Effects: Initializes c with std::move(cont) as the first argument and a as the second argument, and initializes comp with compare; calls
make_heap(c.begin(), c.end(), comp)
.
Section: 20.10.7.6 [meta.trans.other] Status: Tentatively Ready Submitter: Mike Spertus Opened: 2015-09-25 Last modified: 2015-11-04
Priority: Not Prioritized
View other active issues in [meta.trans.other].
View all other issues in [meta.trans.other].
View all issues with Tentatively Ready status.
Discussion:
Addresses: fund.ts.v2
In Library Fundamentals 2 (N4529) 3.3.2p3 [meta.trans.other], the definition of invocation traits for a class object f considers when f is called via a function call operator that is matched by the arguments but ignores the possibility that f may be called via a surrogate call function (C++14 13.3.1.1.2 [over.call.object] p2), in which case, the definition of the invocation parameters may be either incorrect or even unsatisfiable.
[2015-10, Kona Saturday afternoon]
AM: Do we have this trait yet? JW: No, it cannot be implemented without compiler support.
Move to tentatively ready
Proposed resolution:
This wording is relative to N4529.
In Library Fundamentals 2, change [meta.trans.other] as indicated:
-3- Within this section, define the invocation parameters of INVOKE(f, t1, t2, ..., tN) as follows, in which T1 is the possibly cv-qualified type of t1 and U1 denotes T1& if t1 is an lvalue or T1&& if t1 is an rvalue:
[…]
If f is a class object, the invocation parameters are the parameters matching t1, ..., tN of the best viable function (C++14 §13.3.3) for the arguments t1, ..., tN among the function call operators and surrogate call functions of f.
[…]