From d11610f7603a26f28790a59dfdf9c4a44076e643 Mon Sep 17 00:00:00 2001 From: Arthur O'Dwyer Date: Wed, 1 May 2019 16:03:04 -0400 Subject: [PATCH] Should `int(*)()` be convertible to `inplace_function`? Before this patch, we reported that `is_convertible>`, 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 #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>` would be `false`. --- SG14/inplace_function.h | 8 +++++--- SG14_test/inplace_function_test.cpp | 10 ++++++++++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/SG14/inplace_function.h b/SG14/inplace_function.h index 59453966..00306de3 100644 --- a/SG14/inplace_function.h +++ b/SG14/inplace_function.h @@ -105,9 +105,11 @@ template struct vtable template explicit constexpr vtable(wrapper) noexcept : invoke_ptr{ [](storage_ptr_t storage_ptr, Args&&... args) -> R - { return (*static_cast(storage_ptr))( - static_cast(args)... - ); } + { + return static_cast((*static_cast(storage_ptr))( + static_cast(args)... + )); + } }, copy_ptr{ [](storage_ptr_t dst_ptr, storage_ptr_t src_ptr) -> void { ::new (dst_ptr) C{ (*static_cast(src_ptr)) }; } diff --git a/SG14_test/inplace_function_test.cpp b/SG14_test/inplace_function_test.cpp index 5fd228be..db52381d 100644 --- a/SG14_test/inplace_function_test.cpp +++ b/SG14_test/inplace_function_test.cpp @@ -467,6 +467,15 @@ static void test_convertibility_with_qualified_call_operators() static_assert(std::is_convertible>::value, ""); } +static void test_void_returning_function() +{ + auto lambda = []() { return 42; }; + static_assert(std::is_convertible>::value, ""); + stdext::inplace_function f = lambda; + f = lambda; + f(); +} + namespace { struct InstrumentedCopyConstructor { static int copies; @@ -694,6 +703,7 @@ void sg14_test::inplace_function_test() test_move_construction_from_smaller_buffer_is_noexcept(); test_is_convertible(); test_convertibility_with_qualified_call_operators(); + test_void_returning_function(); test_return_by_move(); test_is_invocable(); test_overloading();