Is there any function objects in the boost that are generic equivalents to the std::equal_to, std::greater etc. family of function objects?
Essentially, std::equal_to should become something like
struct generic_equal_to
{
template <class T, class U>
bool operator()(const T& t, const U& u) const
{
return t == u;
}
};
I can see how the generic versions of std::plus etc. might be trickier due to issues with the return type (though the decltype can solve that). I can't see any possible reason why the std::equal_to function object itself should require a template argument, though.
Surely somewhere in boost or in the STL these versions exist? They are, of course, trivial to write, but I very much dislike duplicating library code, especially for something as apparently trivial as this.
EDIT:
As some context as to why I would want this instead of using lambdas, or another function-object generation method:
I was writing a generic boost::fusion sequence comparison function thusly:
template <class T>
bool sequence_equal(const T& left, const T& right)
{
return fusion::all(
fusion::zip(left, right),
fusion::fused<generic_equal_to>());
}
Note the fusion::fused<generic_equal_to> part, which leads to the isse that you can't practically specify a boost::lambda or boost::phoenix function-object by type. I guess one solution might be decltype:
fusion::fused<decltype(_1 == _2)>()
That seems very awkward though, and might not even work, depending on how boost::lambda or boost::phoenix is implemented - I'm really not sure.
I know you can use fusion::make_fused to get around this whole issue, but then you have to instantiate the function object. The solution I thought of, then, would be a non-template equal_to struct - I called mine generic_equal_to.
I know it's a very trivial problem - after all, make_fused(_1 == _2) will probably inline down to much the same assembly as fused<generic_equal_to>. I just couldn't believe that there was no generic_equal_to function object in boost or in the STL anywhere, hence this question.
I don't think there's anything quite as direct as you're asking for, but there are utilities that not only cover your use-cases, but go beyond. They are Boost.Lambda and Boost.Phoenix (the latter being a more generic successor to the lambda library).
Example using Boost.Lambda for generic equality:
#include <boost/lambda/lambda.hpp>
#include <iomanip>
#include <iostream>
struct foo {};
bool operator==(foo, foo) { return true; }
bool operator==(foo, int) { return false; }
template <typename T, typename U, typename Func>
void f(const T& x, const U& y, Func func)
{
std::cout << func(x, y) << std::endl;
}
int main()
{
using namespace boost::lambda; // for placeholders
std::cout << std::boolalpha;
foo a, b;
int i = 0;
f(a, b, _1 == _2);
f(a, i, _1 == _2);
}
And the same, with Phoenix:
#include <boost/phoenix.hpp>
#include <iomanip>
#include <iostream>
struct foo {};
bool operator==(foo, foo) { return true; }
bool operator==(foo, int) { return false; }
template <typename T, typename U, typename Func>
void f(const T& x, const U& y, Func func)
{
std::cout << func(x, y) << std::endl;
}
int main()
{
using namespace boost::phoenix::arg_names; // for placeholders
std::cout << std::boolalpha;
foo a, b;
int i = 0;
f(a, b, arg1 == arg2);
f(a, i, arg1 == arg2);
}
Each of these can be extended to support the other operators in the obvious way (and more generally, into other expressions). I would personally go with Phoenix, because if you find out you need more functionality than lambda offers you won't end up including both.
Now in C++14 there is std::equal_to<void> (that can be also used as std::equal_to<>)
std::equal_to<> is a specialization of std::equal_to with parameter and return type deduced.
template< class T, class U>
constexpr auto operator()( T&& lhs, U&& rhs ) const
-> decltype(std::forward<T>(lhs) == std::forward<U>(rhs));
Returns the result of equality comparison between lhs and rhs.
Docs
Related
This is just an educational question, which could otherwise be avoided entirely by leveraging on tools such as range-v3.
Anyway, consider this example in which a variadic number of containers is passed to a function which returns a tuple of iterators:
#include <tuple>
#include <iostream>
#include <vector>
template <typename ...T>
auto begin(T&... containers) { return std::tuple( begin(containers)... ); }
int main() {
std::vector<int> a{1,2,3};
std::vector<long> b{1000,2000,3000};
auto bg = begin(a,b);
(void) bg;
return 0;
}
Quite a lot of code duplication will be produced by adding the functions for all the other iterator makers (std::[end, cbegin, cend, rbegin, rend]). Therefore I was looking for a way to forward the generic iterator maker function into my function.
I managed to come up with this:
template <auto F, typename ...T>
auto make(T&... containers) { return std::tuple( F(containers)... ); }
// called as this:
auto bg = make<[](auto& c){return std::begin(c);}> (a,b);
...which is more general but comes with an horrendous syntax for the user, Ideally the call should be something like:
auto bg = make<std::begin>(a, b); // or
auto bg = make(std::begin, a, b);
but I have not been able to make these beauties work...
but I have not been able to make these beauties work...
There is no way to make those beauties work currently. The root of it all is that std::begin et al are not functions. They are function templates. Meaning they represent not a single function but an entire family of them. The same is true when you have regular overloads as well. The moment a function name means more than a single function, it can't be passed. An overload set is not a tangible thing we can pass around like a type or a function reference. It's not a callable really.
Wrapping the actual overloaded call into a lambda bypasses the issue entirely. Because a lambda is an object with a type, and those can be passed around just fine. This essentially lifts the overload set up from being a second class citizen. But it comes with boilerplate.
There was a proposal made (p1170) to automatically lift an overload set into a callable, but so far it didn't seem to gain traction. So C++20 doesn't have the means.
As for the boilerplate, we can cut on it if we are willing to employ macros. A simple macro that lifts an overload set correctly can look something like this:
#define LIFT(...) [](auto&& ...args) \
noexcpet(noexcpet(__VA_ARGS__(std::forward<decltype(args)>(args)...))) \
-> decltype(auto) { \
return __VA_ARGS__(std::forward<decltype(args)>(args)...); \
}
Granted, that's a lot of boilerplate by itself, but it handles the exception specification, as well as return type deduction for functions that don't return by value. It also perfect forwards. So while it is indeed fairly ugly, it allows us to write:
auto bg = make(LIFT(std::begin), a, b);
You could wrap those functions within lambdas so you could use it in the next fashion
make(std::begin, a, b);
i.e
template <typename F, typename ...T>
decltype(auto) make(F func, T&... containers) { return std::tuple( func(containers)... ); }
namespace tl {
auto begin = [](auto& c) {
return std::begin(c);
};
}
int main() {
std::vector<int> a{1,2,3};
std::vector<long> b{1000,2000,3000};
auto bg = make(tl::begin, a, b);
(void) bg;
cout << *++std::get<0>(bg) << ' ' << *std::get<1>(bg);
return 0;
}
Depending on your definition of monster, this is easily achievable:
int main()
{
auto v1 = std::vector{1,2,3};
auto v2 = std::vector{4,5,6};
auto begins = std::tie(v1, v2) >> notstd::begin;
auto ends = std::tie(v1, v2) >> notstd::end;
return 0;
}
Here's the boilerplate:
#include <vector>
#include <tuple>
#include <utility>
namespace notstd
{
namespace detail
{
template<class Tuple, class Function, std::size_t...Is>
auto transform_elements(Tuple&& tup, Function f, std::index_sequence<Is...>)
{
return std::make_tuple(f(std::get<Is>(std::forward<Tuple>(tup)))...);
}
}
template<class Tuple, class Transform>
auto operator >> (Tuple&& tup, Transform t)
{
using tuple_type = std::decay_t<Tuple>;
constexpr auto size = std::tuple_size<tuple_type>::value;
return detail::transform_elements(std::forward<Tuple>(tup),
t,
std::make_index_sequence<size>());
}
constexpr auto begin = [](auto&& x)
{
return std::begin(x);
};
constexpr auto end = [](auto&& x)
{
return std::end(x);
};
}
This is by no means a style recommendation.
I often find myself using std::sort, std::max_element, and the like with a lambda that simply invokes a member function
std::vector<MyType> vec;
// populate...
auto m = std::max_element(std::begin(vec), std::end(vec),
[](const MyType& a, const MyType& b) { return a.val() < b.val()})
this feels like a waste of characters and a loss of clarity. I'm aware that I could write another function/callable and pass a function pointer/callable object to these algorithm functions, but I often need to do this sort-by just once in a program and it doesn't strike me as a good way of addressing the problem. What I want to do, ideally is say:
auto m = std::max_element(std::begin(vec), std::end(vec), &MyType::val);
and have the objects be sorted by their val()s. Is there some part of the stdlib I'm overlooking that could assist me with this? or another simple way of doing it? I'd like to make what this is sorting or searching by as obvious as possible.
I'm aware that just &MyType::val isn't enough, I am looking for something that could perhaps wrap it, or provide a similar functionality without obscurring the meaning.
You can use std::mem_fn (or std::tr1::mem_fn)
int main()
{
std::vector<MyType> vec;
auto m = std::max_element(std::begin(vec), std::end(vec), compare_by(std::mem_fn(&MyType::field)));
}
Of course, this assumes that you have a utility like compare_by in your toolbox (as you should :)):
template <typename F>
struct CompareBy {
explicit CompareBy(F&& f) : f(std::forward<F>(f)) {}
template <typename U, typename V>
bool operator()(U const& u, V const& v) const {
return f(u) < f(v);
}
private:
F f;
};
template <typename F>
CompareBy<F> compare_by(F&& f) { return CompareBy<F>(std::forward<F>(f)); }
See it Live On Coliru
You can do it without introducing any new functions (templated or not).
Just use bind and std::less
auto m = std::max_element(vec.begin(), vec.end(),
bind(less<>(), bind(&MyType::val, _1), bind(&MyType::val, _2)));
A templated comparator could help you:
template <typename StructureType,
typename MemberType,
MemberType StructureType::*member>
bool comparator(const StructureType& the_first, const StructureType& the_second)
{
return the_first.*member < the_second.*member;
}
http://ideone.com/K8ytav
A bit of type traits magic could certainly allows you to avoid writing the type.
How about once overloading operator< for your custom type? This can be naturally done inside the class (or directly next to it), and then no further argument is required beside the iterators.
Passing your val() function isn't possible, as you must pass a binary operator.
EDIT: Having read the other valuable alternatives (also sehe's nice response), I want to confirm what I already mentioned in the comment below: In my opinion, nothing beats the readibility, locality and also flexibility of a lambda expression (--on the risk of writing some passages twice).
#Ryan Haining: I suggest you to keep it as in your original post.
An improvement on sehes answer, so as to avoid needing to use std::mem_fn would be provide a pointer to member overload for the compare_by function.
example usage
std::sort(std::begin(vec), std::end(vec), compare_by(&MyType::field));
std::sort(std::begin(vec), std::end(vec), compare_by(&MyType::field, std::greater<>{}));
the code to implement
#include <functional> // std::less
#include <utility> // std::move
#include <type_traits> // std::is_invocable_r
// Forward declaration
template<typename R, typename T, typename F = std::less<R>>
auto compare_by(R T::*, F = F{});
// Implementation
namespace detail {
template<typename T, typename F>
struct compare_by_t;
template<typename R, typename T, typename F>
struct compare_by_t<R T::*, F> : private F
{
compare_by_t(F&& f, R T::*m): F{std::move(f)}, _member{m} {}
R T::* _member;
bool operator()(T const& x, T const& y) const
{
return F::operator()(x .* _member, y .* _member);
}
};
} // detail
template<typename R, typename T, typename F>
auto compare_by(R T::* member, F f)
{
static_assert(std::is_invocable_r<bool, F, R, R>::value);
return detail::compare_by_t<R T::*, F>{ std::move(f), member };
}
Given a callable object ( a function ) a, and an argument b ( or a series of arguments ), I would like to deduce the type returned from f considering that f is overloaded with multiple signatures.
one of my many attempts is
#include <iostream>
#include <cstdint>
#include <string>
#include <functional>
#include <utility>
#include <typeinfo>
int foo(uint32_t a) { return ((a + 0) * 2); }
bool foo(std::string a) { return (a.empty()); }
/*template <typename A, typename B> auto bar(A a, B b) -> decltype(a(b)) {
return (a(b));
}*/
/*template <typename A, typename B> decltype(std::declval<a(b)>()) bar(A a, B b)
{
return (a(b));
}*/
template <typename A, typename B> void bar(std::function<A(B)> a, B b) {
std::cout << a(b) << "\n";
}
int main() {
// the following 2 lines are trivial and they are working as expected
std::cout << foo(33) << "\n";
std::cout << typeid(decltype(foo(std::string("nothing")))).name() << "\n";
std::cout << bar(foo, 33) << "\n";
//std::cout << bar(foo, std::string("Heinz")) << "\n";
return (0);
}
and 2 templates options are commented out and included in the previous code.
I'm using declval result_of auto decltype without any luck.
How does the overloading resolution process works at compile time ?
If anyone wants to know why I'm trying to get creative with this, is that I'm trying to implement some Currying in C++11 in a workable/neat way.
The problem is that you can't easily create a function object from an overload set: when you state foo or &foo (the function decays into a function pointer in most case, I think) you don't get an object but you get an overload set. You can tell the compiler which overload you want by either calling it or providing its signature. As far as I can tell, you don't want either.
The only approach I'm aware of is to turn your function into an actual function object which makes the problem go away:
struct foo_object
{
template <typename... Args>
auto operator()(Args&&... args) -> decltype(foo(std::forward<Args>(args)...)) {
return foo(std::forward<Args>(args)...);
}
};
With that wrapper which is unfortunately needed for each name, you can trivially deduce the return type, e.g.:
template <typename Func, typename... Args>
auto bar(Func func, Args&&... args) -> decltype(func(std::forward<Args>(args)...)) {
// do something interesting
return func(std::forward<Args>(args)...);
}
int main() {
bar(foo_object(), 17);
bar(foo_object(), "hello");
}
It doesn't quite solve the problem of dealing with overload sets but it gets reasonably close. I experimented with this idea, essentially also for the purpose of currying in the context of an improved system of standard library algorithms and I'm leaning towards the algorithms actually being function objects rather than functions (this is desirable for various other reasons, too; e.g., you don't need to faff about when you want to customize on algorithm with another one).
If foo is overloaded, you need to use the following:
#include <type_traits>
int foo(int);
float foo(float);
int main() {
static_assert(std::is_same<decltype(foo(std::declval<int>())), int>::value, "Nope.");
static_assert(std::is_same<decltype(foo(std::declval<float>())), float>::value, "Nope2.");
}
If it's not, then this will suffice:
#include <type_traits>
bool bar(int);
int main() {
static_assert(std::is_same<std::result_of<decltype(bar)&(int)>::type, bool>::value, "Nope3.");
}
Yes, it is verbose because you're trying to explicitly extract what implicit ad-hoc overloading does for you.
This is actually already implemented for you std::result_of. Here is a possible implementation
template<class>
struct result_of;
// C++11 implementation, does not satisfy C++14 requirements
template<class F, class... ArgTypes>
struct result_of<F(ArgTypes...)>
{
typedef decltype(
std::declval<F>()(std::declval<ArgTypes>()...)
) type;
};
I need to pass a function to an operator. Any unary function having correct arg type. Return type can be anything. Because this is library code, I can not wrap it or cast f to specific overload (outside of operator*). Function takes operator* 1st arg as it own argument. Artificial example below compiles and returns correct results. But it has hardcoded int return type—to make this example compile.
#include <tuple>
#include <iostream>
using namespace std;
template<typename T>
int operator* (T x, int& (*f)(T&) ) {
return (*f)(x);
};
int main() {
tuple<int,int> tpl(42,43);
cout << tpl * get<0>;
}
Is it possible to make operator* to accept f with arbitrary return type?
UPDATE - GCC bug?
Code:
#include <tuple>
template<typename T, typename U>
U operator* (T x, U& (*f)(T&) ) {
return (*f)(x);
};
int main() {
std::tuple<int,int> tpl(42,43);
return tpl * std::get<0,int,int>;
}
Compiles and runs correctly with gcc462 and 453 but is reject with gcc471 and 480. So it is possible GCC regression bug. I've submitted bug report:
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54111
EDIT
I've changed example to use tuple as arg - it was possible trivially deduce return type in previous example.
EDIT2
Many people could not understand what is needed, so I've changed call function to operator* to make example more real.
Yes, if this is what you mean:
template<typename T, typename F>
auto call (T x, F f) -> decltype(f(x)) {
return (f)(x);
}
There are actually a lot of ways to do that.
As an answer to your updated question:
as discussed by #DavidRodríguez, get<0> is not enough, nor the syntatically correct &get<0>. What you need is &get<0,int,int>. Follows your example, it would be:
#include <tuple>
using namespace std;
template<typename T, typename U>
U call (T x, U (*f)(T&) ) {
return (*f)(x);
};
int main() {
tuple<int,int> tpl(42,43);
call(tpl, &get<0,int,int>);
return 0;
}
During normal use of std::get<>(), the int,int part is deduced automatically. But in your situation you need to provide it, since there is no parameters. One workaround is a custom get template function:
#include <tuple>
using namespace std;
template <size_t I, typename T>
auto myGet(T& tpl) -> decltype(get<I>(tpl))
{
return get<I>(tpl);
}
template<typename T, typename U>
U call (T x, U (*f)(T&) ) {
return (*f)(x);
};
int main() {
tuple<int,int> tpl(42,43);
auto get0 = &myGet<0, decltype(tpl)>;
call(tpl, get0);
// call(tpl, &myGet<0, decltype(tpl)>); // all in one line, do not work
return 0;
}
You should be able to do this:
template<typename T,typename U>
U call (T x, U (*f)(T) ) {
return (*f)(x);
};
I am trying to simplify (via make_fn()) the generation of functors that preprocess parameters (via wrap()) for member functions of arity n.
Generating the functors is basically working, but until now only by explicitly specifying the parameter types for the member function.
Now i'd like to generate the correct functor from the member function type it handles:
struct X {};
template<class C, typename T1, bool (C::*F)(T1)>
inline // there are more for T1..TN
bool wrap(C* c, X x)
{
return (c->*F)(process<T1>(x));
}
template<class C, typename T1, bool (C::*F)(T1)>
inline // there are more for T1..TN
boost::function<bool (C*, X)> make_fn(F f) // <- problem here, F is not a type
{
return boost::bind(&wrap<C, T1, F>, _1, _2);
}
With this however, vc++ and g++ don't see F as a type for the parameter of make_fn(). I must miss something obvious here and am feeling somewhat blind.
The idea was that it should work like this:
struct A
{
bool f1(bool) { return true; }
};
void test()
{
A a;
X x;
make_fn(&A::f1)(&a, x);
}
Any ideas on how to make that work?
Background:
I have a fixed interface which, when simplified, looks like this:
bool invoke(C* c, const char* const functionName, int argCount, X* args);
X is a variant type which i have to convert to certain backend types (int, std::string, ...).
To handle these calls i have a map of functors that are looked up by name and map these calls to member functions of some instance.
The intention of the wrapping is to avoid manual conversions and instead generate functors which do the conversion for me or throw. I have this working with a macro based solution, but that solution requires to specify the types and the parameter count explicitly.
Via function overload resolution i hope to generate the correct converting functor implicitly from the member function signature.
It appears to me that you are attempting to turn a pointer passed to a function into a non-type template argument, which I'm afraid is not going to work (see comments to your question).
What you could do, is to store the function pointer in a function object. The following appears to compile:
#include <boost/bind.hpp>
#include <boost/function.hpp>
struct X {};
template <class T>
bool process(X) { return true; }
template <class C, class T1, class Func>
struct wrap1
{
typedef bool result_type;
Func f;
wrap1(Func f): f(f) {}
bool operator()(C* c, X x)
{
return (c->*f)(process<T1>(x));
}
};
template<class C, typename T1>
inline // there are more for T1..TN
boost::function<bool (C*, X)> make_fn(bool (C::*f)(T1))
{
return boost::bind(wrap1<C, T1, bool (C::*)(T1)>(f), _1, _2);
}
struct A
{
bool f1(bool) { return true; }
};
void test()
{
A a;
X x;
make_fn(&A::f1)(&a, x);
}
However, I'm not sure if that is any good and how you would create the rest of the wrappers. For the latter you might just get a compiler that supports variadic templates. :)