std::experimental::function constructors taking allocator arguments may throw exceptionsSection: 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
functionconstructor that takes a first argument of typeallocator_arg_tis 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 theexperimental::functionclass template, then that move or copy is performed by using-allocator construction with allocatorget_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:
-?- Throws: May throw!*this if !f; otherwise,*thistargets a copy off.target().bad_allocor 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, wheref'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,*thishas no target; otherwise, move-constructs the target offinto the target of*this, leavingfin a valid state with an unspecified value.template <class F, class A> function(allocator_arg_t, const A& a, F f);-?- Requires:
-?- Remarks: This constructor shall not participate in overload resolution unlessFshall beCopyConstructible.fis Callable (C++14 §20.9.11.2) for argument typesArgTypes...and return typeR. -?- Postconditions:!*thisif any of the following hold:-?- Otherwise,
fis a null function pointer value.
fis a null member pointer value.
Fis an instance of thefunctionclass template, and!f.*thistargets a copy offinitialized withstd::move(f). [Note: Implementations are encouraged to avoid the use of dynamically allocated memory for small callable objects, for example, wheref's target is an object holding only a pointer or reference to an object and a member function pointer. — end note] -?- Throws: May throwbad_allocor any exception thrown byF's copy or move constructor.-2- In the following descriptions, let
[…]ALLOCATOR_OF(f)be the allocator specified in the construction offunction f, orallocator<char>()if no allocator was specified.