Skip to content

Commit

Permalink
Should int(*)() be convertible to inplace_function<void()>?
Browse files Browse the repository at this point in the history
Before this patch, we reported that `is_convertible<int(*)(), inplace_function<void()>>`,
but if you actually tried to do it, you got a compiler error down in the guts
of `inplace_function`.

After this patch, we let you do it.

However, see issue WG21-SG14#150: I think anyone who relies on this behavior is probably
doing so unintentionally (and their code is probably wrong). Therefore, maybe we
should change our SFINAE so that `is_convertible<int(*)(), inplace_function<void()>>`
would be `false`.
  • Loading branch information
Quuxplusone committed May 23, 2019
1 parent 6ce8d84 commit 50c3b31
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 3 deletions.
8 changes: 5 additions & 3 deletions SG14/inplace_function.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,11 @@ template<typename R, typename... Args> struct vtable

template<typename C> explicit constexpr vtable(wrapper<C>) noexcept :
invoke_ptr{ [](storage_ptr_t storage_ptr, Args&&... args) -> R
{ return (*static_cast<C*>(storage_ptr))(
static_cast<Args&&>(args)...
); }
{
return static_cast<R>((*static_cast<C*>(storage_ptr))(
static_cast<Args&&>(args)...
));
}
},
copy_ptr{ [](storage_ptr_t dst_ptr, storage_ptr_t src_ptr) -> void
{ ::new (dst_ptr) C{ (*static_cast<C*>(src_ptr)) }; }
Expand Down
16 changes: 16 additions & 0 deletions SG14_test/inplace_function_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -510,6 +510,21 @@ static void test_convertibility_with_lambdas()
static_assert(!std::is_convertible<decltype(f), stdext::inplace_function<void(int&)>>::value, "");
}

static void test_void_returning_function_runtime()
{
auto lambda = []() { return 42; };
static_assert(std::is_convertible<decltype(lambda), stdext::inplace_function<void()>>::value, "");
static_assert(std::is_convertible<decltype(lambda), stdext::inplace_function<const void()>>::value, "");

stdext::inplace_function<void()> f = lambda;
f = lambda;
f();

stdext::inplace_function<const void()> g = lambda;
g = lambda;
g();
}

namespace {
struct InstrumentedCopyConstructor {
static int copies;
Expand Down Expand Up @@ -703,6 +718,7 @@ void sg14_test::inplace_function_test()
test_is_convertible();
test_convertibility_with_qualified_call_operators();
test_convertibility_with_lambdas();
test_void_returning_function_runtime();
test_return_by_move();
test_is_invocable();
test_overloading_on_arity();
Expand Down

0 comments on commit 50c3b31

Please sign in to comment.