Closed LYP951018 closed 7 years ago
That repro technically should result in a compile error, since the Callable
concept only admits function objects and decltype(Foo)
is a function type, not an object type. It would, however, be nice if this nearly identical program worked:
#include <range/v3/utility/functional.hpp>
void __stdcall Foo() {}
int main()
{
CONCEPT_ASSERT(ranges::Callable<decltype(&Foo)>::value);
}
which does test a function object type.
The root failure here is that range-v3 wants to wrap function pointers in an object of type ptr_fn_
when passing them through as_function
:
template<typename R, typename...Args>
struct ptr_fn_
{
private:
R (*pfn_)(Args...);
public:
ptr_fn_() = default;
explicit ptr_fn_(R (*pfn)(Args...))
: pfn_(pfn)
{}
R operator()(Args...args) const
{
return (*pfn_)(std::forward<Args>(args)...);
}
};
// ... later, defining an operator() overload of `as_function`:
template<typename R, typename ...Args>
ptr_fn_<R, Args...> operator()(R (*p)(Args...)) const
{
return ptr_fn_<R, Args...>(p);
}
This overload is not viable for non-default calling conventions, and the others refuse function pointers of all kinds, so as_function
effectively does not accept non-default calling convention function pointers. However, there seems to be no reason to wrap function pointers: they are already perfectly good function object types. I think we can eliminate the ptr_fn_
class template and relax the constraints on the as_function_fn::operator()
overload that simply returns its argument so that it also accepts function pointers and have an equivalent as_function
that also works with non-default calling conventions.
I recall creating ptrfn because I was inheriting from the result of as_function in places to take advantage of EBO.
I recall creating ptrfn because I was inheriting from the result of as_function in places to take advantage of EBO.
That is no longer the case. If it were, we could easily wrap the result in a box<>
that can provide EBO-as-a-service.
leads to compile error.