You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
function_ref has two constructors for functor (excluding the overloading of the one whose argument type is a lambda that can be converted to a function pointer):
function_ref<int(int, int)> a([](int a, int b) { return a + b; });
REQUIRE(a(1, 3) == 4);
function_ref<int(int, short)> b(a);
REQUIRE(b(1, 3) == 4);
function_ref<void(int, int)> c(a);
c(1, 3);
}
As you can see, it uses the first overload!
This makes sense, because the first overload can obviously accept such a construct. I'd even go so far as to say that the second construct is obviously wrong (it's just that it's never called, so it doesn't generate an error for now).
using storage = detail::aligned_union<void*, Return (*)(Args...)>;
using callback = Return (*)(constvoid*, Args...);
Relies on the template parameters Return and Args, so it is obviously not possible to simply convert a variable of a different type to the desired type.
Even so, it is clear that calling the first overload is not as expected.
If a function is passed a function_ref by copy construction, then there is an intermediate state that holds the function_ref.
classState
{
// ...private:// ....
function_ref<int(int, int)> function_;
// ....
};
autofoo(int a, double b, std::string c, function_ref<int(int, int)> function) -> void
{
// ...
State state{a, b, c, function};
// ....
}
autobar(function_ref<int(int, int)> function) -> void
{
// ...foo(42, 3.14, "hello world", function);
// ...
}
automain() -> int
{
int i = 42;
auto lambda = [&i](int a, int b) -> int { return i + a + b; };
bar(lambda);
}
The result may not be as expected, and may even lead to segmentation fault! Because the function_ in State references another function_ref that may be destructed.
So the first overloading candidate should be restricted so that the above case calls a copy construct of function_ref.
After that I'll start a PR where I'll restrict the first overload, remove the second one, and add a new overload like the second one to allow for automatic conversion of function_refs where the return type and parameter type is compatible with that function_ref, but this will cause the constructed function_ref to refer directly to the incoming function_ref.
The text was updated successfully, but these errors were encountered:
Life4gal
added a commit
to Life4gal/type_safe
that referenced
this issue
Jul 21, 2023
function_ref
has two constructors forfunctor
(excluding the overloading of the one whose argument type is a lambda that can be converted to a function pointer):type_safe/include/type_safe/reference.hpp
Lines 592 to 621 in a80a3ed
It looks like this part of the test case is for testing the second constructor, but in fact, it's not!
type_safe/test/reference.cpp
Lines 308 to 318 in a80a3ed
As you can see, it uses the first overload!
This makes sense, because the first overload can obviously accept such a construct. I'd even go so far as to say that the second construct is obviously wrong (it's just that it's never called, so it doesn't generate an error for now).
Obviously:
type_safe/include/type_safe/reference.hpp
Lines 676 to 677 in a80a3ed
Relies on the template parameters
Return
andArgs
, so it is obviously not possible to simply convert a variable of a different type to the desired type.type_safe/include/type_safe/reference.hpp
Line 620 in a80a3ed
Even so, it is clear that calling the first overload is not as expected.
If a function is passed a function_ref by copy construction, then there is an intermediate state that holds the function_ref.
The result may not be as expected, and may even lead to segmentation fault! Because the
function_
inState
references another function_ref that may be destructed.So the first overloading candidate should be restricted so that the above case calls a copy construct of function_ref.
After that I'll start a PR where I'll restrict the first overload, remove the second one, and add a new overload like the second one to allow for automatic conversion of
function_ref
s where thereturn type and parameter type
is compatible with that function_ref, but this will cause the constructed function_ref to refer directly to the incoming function_ref.The text was updated successfully, but these errors were encountered: