Title
not_fn call_wrapper can form invalid types
Status
c++17
Section
[func.not.fn]
Submitter
Jonathan Wakely

Created on 2016-08-19.00:00:00 last changed 82 months ago

Messages

Date: 2016-09-12.04:36:33

Proposed resolution:

This wording is relative to N4606.

  1. 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&&...)>>());
      […]
    };
    
  2. 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&&...)>>());
    
Date: 2016-09-09.00:00:00

[ 2016-09-09 Issues Resolution Telecon ]

P0; move to Tentatively Ready

Date: 2016-11-01.19:58:26

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.

The return types should use result_of_t<F(Args&&...)> instead.

History
Date User Action Args
2017-07-30 20:15:43adminsetstatus: wp -> c++17
2016-11-14 03:59:28adminsetstatus: pending -> wp
2016-11-14 03:55:22adminsetstatus: ready -> pending
2016-09-12 04:36:33adminsetmessages: + msg8508
2016-09-12 04:36:33adminsetstatus: new -> ready
2016-09-04 18:30:31adminsetmessages: + msg8491
2016-08-19 00:00:00admincreate