This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of C++17 status.
not_fn call_wrapper can form invalid typesSection: 22.10.13 [func.not.fn] Status: C++17 Submitter: Jonathan Wakely Opened: 2016-08-19 Last modified: 2021-06-06
Priority: 0
View all other issues in [func.not.fn].
View all issues with C++17 status.
Discussion:
The definition of the call_wrapper type in the C++17 CD means this
fails to compile:
#include <functional>
struct abc { virtual void f() const = 0; };
struct derived : abc { void f() const { } };
struct F { bool operator()(abc&) { return false; } };
derived d;
bool b = std::not_fn(F{})(static_cast<abc&&>(d));
The problem is that the return types use result_of_t<F(abc)> and
F(abc) is not a valid function type, because it takes an abstract
class by value.
result_of_t<F(Args&&...)> instead.
[2016-09-09 Issues Resolution Telecon]
P0; move to Tentatively Ready
Proposed resolution:
This wording is relative to N4606.
Modify [func.not_fn], class call_wrapper synopsis, as indicated:
class call_wrapper
{
[…]
template<class... Args>
auto operator()(Args&&...) &
-> decltype(!declval<result_of_t<FD&(Args&&...)>>());
template<class... Args>
auto operator()(Args&&...) const&
-> decltype(!declval<result_of_t<FD const&(Args&&...)>>());
template<class... Args>
auto operator()(Args&&...) &&
-> decltype(!declval<result_of_t<FD(Args&&...)>>());
template<class... Args>
auto operator()(Args&&...) const&&
-> decltype(!declval<result_of_t<FD const(Args&&...)>>());
[…]
};
Modify the prototype declarations of [func.not_fn] as indicated:
template<class... Args> auto operator()(Args&&... args) & -> decltype(!declval<result_of_t<FD&(Args&&...)>>()); template<class... Args> auto operator()(Args&&... args) const& -> decltype(!declval<result_of_t<FD const&(Args&&...)>>());[…]
template<class... Args> auto operator()(Args&&... args) && -> decltype(!declval<result_of_t<FD(Args&&...)>>()); template<class... Args> auto operator()(Args&&... args) const&& -> decltype(!declval<result_of_t<FD const(Args&&...)>>());