This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of Resolved status.
Section: 4.2 [fund.ts.v2::func.wrap.func] Status: Resolved Submitter: Tim Song Opened: 2015-12-05 Last modified: 2022-11-22
Priority: 3
View all other issues in [fund.ts.v2::func.wrap.func].
View all issues with Resolved status.
Discussion:
Addresses: fund.ts.v2
[This is essentially LWG 2370, but deals with the fundamentals TS version rather than the one in the standard]
In 4.2 [fund.ts.v2::func.wrap.func] of library fundamentals TS, the constructorstemplate<class A> function(allocator_arg_t, const A&) noexcept; template<class A> function(allocator_arg_t, const A&, nullptr_t) noexcept;
must type-erase and store the provided allocator, since the operator= specification requires using the "allocator specified in the construction of" the std::experimental::function object. This may require a dynamic allocation and so cannot be noexcept. Similarly, the following constructors
template<class A> function(allocator_arg_t, const A&, const function&); template<class A> function(allocator_arg_t, const A&, function&&); template<class F, class A> function(allocator_arg_t, const A&, F);
cannot satisfy the C++14 requirement that they "shall not throw exceptions if [the function object to be stored] is a callable object passed via reference_wrapper or a function pointer" if they need to type-erase and store the allocator.
[2016-11-08, Issaquah]
Not adopted during NB comment resolution
[2022-10-12 LWG telecon]
Set status to "Open". This would be resolved by P0987R2.
[2022-11-22 Resolved by P0897R2 accepted in Kona. Status changed: Open → Resolved.]
Proposed resolution:
This wording is relative to N4562.
Edit 4.2 [fund.ts.v2::func.wrap.func], class template function synopsis, as follows:
namespace std { namespace experimental { inline namespace fundamentals_v2 { […] template<class R, class... ArgTypes> class function<R(ArgTypes...)> { public: […] template<class A> function(allocator_arg_t, const A&)noexcept; template<class A> function(allocator_arg_t, const A&, nullptr_t)noexcept; […] }; […] } // namespace fundamentals_v2 } // namespace experimental […] } // namespace std
Insert the following paragraphs after 4.2.1 [fund.ts.v2::func.wrap.func.con]/1:
[Drafting note: This just reproduces the wording from C++14 with the "shall not throw exceptions for reference_wrapper/function pointer" provision deleted. — end drafting note]
-1- When a function constructor that takes a first argument of type allocator_arg_t is invoked, the second argument is treated as a type-erased allocator (8.3). If the constructor moves or makes a copy of a function object (C++14 §20.9), including an instance of the experimental::function class template, then that move or copy is performed by using-allocator construction with allocator get_memory_resource().
template <class A> function(allocator_arg_t, const A& a); template <class A> function(allocator_arg_t, const A& a, nullptr_t);-?- Postconditions: !*this.
template <class A> function(allocator_arg_t, const A& a, const function& f);-?- Postconditions: !*this if !f; otherwise, *this targets a copy of f.target().
-?- Throws: May throw bad_alloc or any exception thrown by the copy constructor of the stored callable object. [Note: Implementations are encouraged to avoid the use of dynamically allocated memory for small callable objects, for example, where f's target is an object holding only a pointer or reference to an object and a member function pointer. — end note]template <class A> function(allocator_arg_t, const A& a, function&& f);-?- Effects: If !f, *this has no target; otherwise, move-constructs the target of f into the target of *this, leaving f in a valid state with an unspecified value.
template <class F, class A> function(allocator_arg_t, const A& a, F f);-?- Requires: F shall be CopyConstructible.
-?- Remarks: This constructor shall not participate in overload resolution unless f is Callable (C++14 §20.9.11.2) for argument types ArgTypes... and return type R. -?- Postconditions: !*this if any of the following hold:-?- Otherwise, *this targets a copy of f initialized with std::move(f). [Note: Implementations are encouraged to avoid the use of dynamically allocated memory for small callable objects, for example, where f's target is an object holding only a pointer or reference to an object and a member function pointer. — end note] -?- Throws: May throw bad_alloc or any exception thrown by F's copy or move constructor.
f is a null function pointer value.
f is a null member pointer value.
F is an instance of the function class template, and !f.
-2- In the following descriptions, let ALLOCATOR_OF(f) be the allocator specified in the construction of function f, or allocator<char>() if no allocator was specified.
[…]