combining 3 functors into 1 - c++

I have 3 functors and was wondering if these can be combined into 1, perhaps as a template.
is it possible? if so, how would I do it. thx!
struct less_than
{
bool operator()(double prev,double curr) const
{
return prev<curr;
}
};
struct great_than
{
bool operator()(double prev,double curr) const
{
return prev>curr;
}
};
struct equal_to
{
bool operator()(double prev, double curr) const
{
return prev==curr;
}
};

If you mean, specialized by the operator, then the answer is, no, not at the language level.
Luckily, the STL already provides functors for this (std::equal_to, etc.). You can either use these directly, or use them as arguments to your own function classes.

As these are all existent in the standard library, you can just do
template<class F>
struct compare
{
compare(F _f)
: f(_f) {};
bool operator()(double prev, double curr) const
{
return f(prev, curr);
}
F f;
};
And use e.g. compare< std::less<double> >. But this would be quite useless, as you can just use the standard library functors directly.

You can do something like this:
class Functors
{
private:
bool f1(double, double)
{
}
bool f2(double, double)
{
}
bool f3(double, double)
{
}
public:
bool test(int op, double a, double b)
{
//better use function selector, this is only simple example
if (op == 1)
return f1(a, b);
if (op == 2)
return f2(a, b);
if (op == 3)
return f3(a, b);
}
};
use it:
vector<double> v;
int op = select_op();
//sort vector
std::sort(v.begin(), v.end(), boost::bind(&Functors::test, Functors(), op, _1, _2));

Related

Change Operation at runtime in C++

I have a small problem at hand. Suppose there is a if condition with only 2 operands but I want to make the operation dynamic.
void somFunc()
{
if(a && b) /*1*/
{
}
else if(a1 && b1) /*2*/
{
}
else if(a || b) /*3*/
{
}
else if(a1 || b1) /*4*/
}
Basically, 1 and 3 exactly has same parameters with different operation,Similarly for 2 and 4. I want to reduce these 4 operations to 2.
I want to know if there is a way I can make oper dynamic. Consider we only have 2 operations && and ||Can I use templates in any way ?
If someone wants to know why I need this is, there are n if conditions inside a big if/else. If I somehow achieve this, I reduce the conditions by half.
Not sure if this is what you are asking for, but you can write something like this:
enum OPERATION { AND, OR };
bool operation(bool a, bool b,OPERATION op) {
if (op == AND) return a && b;
return a || b;
}
void somFunc(OPERATION op)
{
if(operation(a,b,op))
{
}
}
Or as suggested in a comment, make the operation to be performed a parameter of the function, like so
template <OPERATION>
void somFunc(OPERATION op)
{
if(op(a,b))
{
}
}
and call it like this
somFunc( [](bool a, bool b) { return a && b; });
somFunc( [](bool a, bool b) { return a || b; });
You can use pointers to funtions.
#include <iostream>
#include <functional>
bool oper1(bool a, bool b) {
return a || b;
}
bool oper2(bool a, bool b) {
return a && b;
}
int main() {
bool a = true, b = false;
auto oper = oper1;
if (oper(a, b)) {
std::cout << "OR\n";
}
oper = oper2;
if (oper(a, b)) {
std::cout << "AND\n";
}
}
First you define all your conditions and later you can switch the condition by setting the variable.
You can also use inheritance and functors:
#include <iostream>
#include <functional>
#include <memory>
class Operator {
public:
virtual bool eval(bool a, bool b) = 0;
};
class OrOperator : public Operator {
public:
bool eval(bool a, bool b) {
return a || b;
}
};
class AndOperator : public Operator {
public:
bool eval(bool a, bool b) {
return a && b;
}
};
class VariableOperator : public Operator {
public:
VariableOperator(bool val) : val(val) {}
bool eval(bool a, bool b) {
return val;
}
private:
bool val;
};
int main() {
bool a = true, b = false;
std::unique_ptr<Operator> oper(new OrOperator);
if (oper->eval(a, b)) {
std::cout << "OR\n";
}
oper.reset(new AndOperator);
if (oper->eval(a, b)) {
std::cout << "AND\n";
}
oper.reset(new VariableOperator(true));
if (oper->eval(a, b)) {
std::cout << "VARIABLE\n";
}
}
You might be looking for something like this:
void somFunc()
{
std::vector< std::function< bool(bool, bool) > > operators = {
[](bool a, bool b){ return a && b; },
[](bool a, bool b){ return a || b; }
};
for ( auto& op : operators )
{
if ( op( a, b ) )
{
}
else if ( op( a1, b1 ) )
{
}
}
}
You can add more operators or change the parameter types easily enough.
You can do this with CRTP too:
#include <iostream>
#include <string>
#include <memory>
template<class T>
class Operation
{
public:
bool eval(bool a, bool b)
{
return this->impl().eval(a,b);
}
private:
T& impl() { return static_cast<T&>(*this); }
};
class AndOperation : public Operation<AndOperation>
{
public:
bool eval(bool a, bool b)
{
return a && b;
}
};
class OrOperation : public Operation<OrOperation>
{
public:
bool eval(bool a, bool b)
{
return a || b;
}
};
int main()
{
AndOperation andOp;
auto anonOp = std::make_unique<OrOperation>();
std::cout << andOp.eval(true, true) << std::endl;
std::cout << anonOp->eval(false,false);
}
see live example here
What are the advantages of CRTP over virtual inheritance?
CRTP is a case of static polymorphism. Here's some references:
Compile time vs run time polymorphism in C++ advantages/disadvantages
What is the motivation behind static polymorphism in C++?
C++: How is this technique of compile-time polymorphism called and what are the pros and cons?
The cost of dynamic (virtual calls) vs. static (CRTP) dispatch in C++
It is possible to make somFunc() a template, and accept any function that accepts two arguments and returns a value that can be tested with if.
#include <functional> // for binary operations in std
template<class Operation> void somfunc(Operation oper)
{
if (oper(a,b))
{
// whatever
}
}
int main()
{
somFunc(std::logical_and<int>());
somFunc(std::logical_or<int>());
somFunc(std::plus<int>()); // addition
// pass a lambda
somFunc([](int a, int b) -> int {return a + b;}); // lambda form of addition
}
In the above, I've assumed the variables a and b (which have been used in the question, but types unspecified) are of type int.

Mapping functions with variable arguments and calling by string c++

I would like to have some fair idea how to map functions with variable arguments,return type of int and call it by a string..
Just for an example...
int func1(int a, int b);
int func2(int a1, int b1 , int* c1);
int func3(char* dummy);
int func4(double x, long y, int z, char** table);
int func5(double d1, double b1);
int func6(int* p, double* q, int i);
I just need a common function called
int CallFunction("funcname", param1, param2, ...);
for example
CallFunction("func1", 10, 20); /* calling function func1 and return func1 result*/
I know how to map functions using functions pointers having constant arguments but variable arguments seems to be complicated.. could anyone shower some idea how to do it.
I even explored Variadic templates.. But seems to complicated calling functions using strings..
I had exact the same problem.
Solved it with this solution:
#include <iostream>
#include <map>
#include <string>
int func0(int x)
{
std::cout << x << std::endl;
}
int func1(int x, int y)
{
std::cout << (x + y) << std::endl;
}
template <class... Args>
struct MapHolder{
static std::map<std::string, int (*)(Args...)> CallbackMap;
};
template <class... Args>
std::map<std::string, int (*)(Args...)> MapHolder<Args...>::CallbackMap;
class Callback {
public:
template <class ...Args>
void RegisterFunction(std::string name, int (*func)(Args...)) {
MapHolder<Args...>::CallbackMap[name] = func;
}
template <class ...Args>
int ExecuteFunction(std::string name, Args &&... args) {
return MapHolder<Args...>::CallbackMap[name](std::forward<Args>(args)...);
};
};
int main(int argc, char *argv[])
{
Callback cb;
cb.RegisterFunction("func0", &func0);
cb.RegisterFunction("func1", &func1);
cb.ExecuteFunction("func0", 42);
cb.ExecuteFunction("func1", 42, 42);
return 0;
}
This snippet is based on this answer. I only use other class/function names.
I'm not sure if this is what you're looking for, but anyway...
1. Creating a generic value holder
boost.any didn't make it into the standard, and, in case you don't know what it is, it allows you to store any C++ value in a single type (any) and get it back if you know the type. The following is a toy implementation of it:
struct TypeHandler {
void* (*copyFrom)(void *src);
void (*destroy)(void *p);
};
template<typename T>
TypeHandler *thandler() {
struct THandler {
static void *copyFrom(void *p) { return new T(*(T *)p); }
static void destroy(void *p) { delete (T *)p; }
};
static TypeHandler th = { &THandler::copyFrom, &THandler::destroy };
return &th;
}
TypeHandler contains two pointer to functions that know how to copy and how to destroy a specific C++ type. A Value can hold any type because it's composed of a void * and a pointer to a TypeHandler. When copying or destroying is required on the instance it asks to the specific type handler function...
struct Value {
TypeHandler *th;
void *p;
Value(const Value& other) : th(other.th), p(th->copyFrom(other.p)) { }
template<typename T> Value(const T& x) : th(thandler<T>()), p(new T(x)) { }
~Value() { th->destroy(p); }
Value& operator=(const Value& other) {
if (this != &other) {
th->destroy(p);
th = other.th;
p = th->copyFrom(other.p);
}
return *this;
}
template<typename T>
Value& operator=(const T& other) {
th->destroy(p);
th = thandler<T>();
p = new T(other);
return *this;
}
template<typename T>
T& to() const {
if (th != thandler<T>()) throw Error("type mismatch");
return *(T*)p;
}
};
Note that Value is copyable and can be passed by value and can be returned by functions.
Any copyable object is implicitly convertible into a Value and I can also convert it back to the original type with to<T>().
2. Creating the name->function maps
std::map<std::string, Value (*)(const Value&)> map1;
std::map<std::string, Value (*)(const Value&, const Value&)> map2;
Value call(const std::string& name, const Value& x1) {
return map1.at(name)(x1);
}
Value call(const std::string& name, const Value& x1, const Value& x2) {
return map2.at(name)(x1, x2);
}
Here I've created explicit maps for 1 and 2 arguments. May be this can be done using C++11 variadic templates, I didn't try. In C++03 libraries it's common to see this kind of stuff copy-n-pasted up to say n=20 to cover reasonable cases.
3. Macrology
To simplify registration of functions I wrote two ugly macros. May be this can be done also using variadic macros or templates (I'm not so sure about it, especially the automatic registration of the wrapper in the map).
#define regfunc1(name, t1) \
Value name(const Value& x1) { \
return name(x1.to<t1>()); \
} \
struct name##_ { \
name##_() { map1[#name]=&name; } \
} name##_instance
#define regfunc2(name, t1, t2) \
Value name(const Value& x1, const Value& x2) { \
return name(x1.to<t1>(), x2.to<t2>()); \
} \
struct name##_ { \
name##_() { map2[#name]=&name; } \
} name##_instance
4. Use
double square(double x) {
return x*x;
}
double hyp2(double x, double y) {
return x*x+y*y;
}
int mylen(const std::string& s) {
return s.size();
}
regfunc1(square, double);
regfunc2(hyp2, double, double);
regfunc1(mylen, std::string);
int main() {
Value x = 42;
Value y = std::string("This is a test");
Value z = 3.14;
printf("%0.3f\n", call("square", z).to<double>());
printf("%0.3f\n", call("hyp2", z, z).to<double>());
printf("mylen(\"%s\") = %i\n",
y.to<std::string>().c_str(),
call("mylen", y).to<int>());
return 0;
}

Can I write a C++ functor that accepts both a raw pointer and a smart pointer?

Given the following:
struct Foo
{
int bar() const;
};
struct IsEqual : public std::unary_function<Foo*, bool>
{
int val;
IsEqual(int v) : val(v) {}
bool operator()(const Foo* elem) const
{
return elem->bar() == val;
}
};
I have a container of Foo* and I use std::find_if and std::not1 to find out if there are any elements in the container where bar() returns something different from a given value. The code looks like this:
// Are all elements equal to '2'?
bool isAllEqual(const std::vector<Foo*> &vec)
{
return find_if(vec.begin(), vec.end(), std::not1(IsEqual(2))) == vec.end();
}
Fast-forward into the future and I now have a different container, this time containing std::tr1::shared_ptr<Foo>. I'd love to simply re-use my functor in an overloaded version of isAllEqual(). But I can't. Foo* and shared_ptr<Foo> are different types. And I need to inherit from unary_function so I can use not1. It'd be more elegant if I could avoid writing the same functor twice.
Questions:
Is there any way to write IsEqual so it can use both raw and smart pointers?
Did I handcuff myself by using std::not1? Should I just write IsNotEqual instead?
Restrictions:
I can't use anything from the boost library.
Our compiler isn't cool enough to support C++0x lambdas.
How about:
template<typename T>
struct IsEqual : public std::unary_function<const T&, bool>
{
int val;
IsEqual(int v) : val(v) {}
bool operator()(const T& elem) const
{
return elem->bar() == val;
}
};
template<typename T>
IsEqual<T> DeduceEqualityComparer(int v, T) { return IsEqual<T>(v); }
// Are all elements equal to '2'?
template<typename TContainer>
bool isAllEqual(const TContainer& coll)
{
using std::begin; // in C++0x, or else write this really simple function yourself
using std::end;
if (begin(coll) == end(coll)) return true;
return find_if(begin(coll), end(coll), std::not1(DeduceEqualityComparer(2, *begin(coll)))) == end(coll);
}
// --*-- C++ --*--
#include <vector>
#include <algorithm>
#include <iostream>
// Template unary function example.
template <typename T>
struct IsEqual : public std::unary_function<T, bool>
{
int v;
IsEqual (int v) : v (v) {}
bool operator () (const T & elem) const
{
return elem ? elem->bar () == v : false;
}
};
// Generic algorithm implementation example...
template <typename T1, typename T2>
bool isAllEqual (const T1 & c, T2 v)
{
return find_if (
c.begin (), c.end (),
std::not1 (IsEqual <typename T1::value_type> (v))) == c.end ();
}
// Some arbitrary pointer wrapper implementation,
// provided just for an example, not to include any
// specific smart pointer implementation.
template <typename T>
class WrappedPtr
{
const T *v;
public:
typedef void (WrappedPtr<T>::*unspecified_boolean_type) () const;
WrappedPtr (const T *v) : v (v) {}
const T *operator -> () const { return v; }
operator unspecified_boolean_type () const
{
return v != NULL ?
&WrappedPtr<T>::unspecified_boolean_true : NULL;
}
private:
void unspecified_boolean_true () const {}
};
// Example of structure that could be used with our algorithm.
struct Foo
{
int v;
Foo (int v) : v (v) {}
int bar () const
{
return v;
}
};
// Usage examples...
int main ()
{
Foo f1 (2), f2 (2);
// Example of using raw pointers...
{
std::vector<Foo *> vec;
vec.push_back (NULL);
vec.push_back (&f1);
vec.push_back (&f2);
if (isAllEqual (vec, 2))
std::cout << "All equal to 2" << std::endl;
else
std::cout << "Not all equal to 2" << std::endl;
}
// Example of using smart pointers...
{
std::vector< WrappedPtr<Foo> > vec;
vec.push_back (NULL);
vec.push_back (&f1);
vec.push_back (&f2);
if (isAllEqual (vec, 2))
std::cout << "All equal to 2" << std::endl;
else
std::cout << "Not all equal to 2" << std::endl;
}
}
My shot would be something like this:
template<typename PtrToFoo>
struct IsEqual : public std::unary_function<PtrToFoo, bool>
{
int val;
IsEqual(int v) : val(v) {}
bool operator()(PtrToFoo elem) const
{
return elem->bar() == val;
}
};
You'll have a different operator() instantiation for everything dereferencable with ->, so raw pointers and smart pointers.
You could maybe do something tricky with implicit conversions:
class IsEqualArg {
public:
// Implicit conversion constructors!
IsEqualArg(Foo* foo) : ptr(foo) {}
IsEqualArg(const std::tr1::shared_ptr<Foo>& foo) : ptr(&*foo) {}
private:
Foo* ptr;
friend struct IsEqual;
};
struct IsEqualArg : public std::unary_function<IsEqualArg, bool> {
bool operator()( const IsEqualArg& arg ) const;
//...
};
But I'd really rather just write a IsNotEqual.
Ben's answer is really the only thing you can do in c++03. In C++0x though, and/or with boost::bind, you don't need to inherit from unary_function. This allows you to use a templated () operator. You can usually get away with the same in C++03 but I think that it's technically incorrect to do so.

find int inside struct with find_if for std::list with structs

How can I use find_if with a std::list if the list contains structs? My first pseudo code attempt at this looks like this:
typename std::list<Event>::iterator found =
find_if(cal.begin(), cal.last(), predicate);
The problem here is that the predicate is not directly visible in the list but inside event.object.return_number(). How am I suppose to refer to an int that is nested inside the struct and needs a get method to be accessed.
You can use a functor class (which is like a function, but allows you to have state, such as configuration):
class Predicate
{
public:
Predicate(int x) : x(x) {}
bool operator() (const Cal &cal) const { return cal.getter() == x; }
private:
const int x;
};
std::find_if(cal.begin(), cal.end(), Predicate(x));
In C++0x, which your compiler probably already partially implements, you can do the following:
find_if(cal.begin(), cal.last(), [&](const Event& e)
{
return e.object.return_number() == value_to_find;
});
You set up your predicate something like this:
struct IsEventObjectReturnNumber
{
int num;
explicit IsEventObjectReturnNumber( int n ) : num( n ) {}
bool operator()(const Event & event ) const
{
return event.object.return_number() == num;
}
};
std::list<Event>::iterator = std::find_if(cal.begin(), cal.end(), IsEventObjectReturnNumber(x));
The (not so simple, but) simplest way (in the absence of C++11) is a custom comparator:
struct CompareMyStruct {
int n_;
CompareMyStruct(int n) : n_(n) { }
bool operator()(const Event& a) const {
return a.object.return_number() == n_;
}
};
typename std::list<Event>::iterator found =
find_if(cal.begin(), cal.last(), CompareMyStruct(123));

generic lookup method?

I'd like a generic method for retrieving the data from a vector.
I have a the following class and vector:
class myClass
{
public:
myClass(int myX, float myZ, std::string myFoo)
: x ( myX )
, z ( myZ )
, foo ( myFoo )
{
}
myClass()
{
}
int x;
float z;
std::string foo;
} ;
std::vector < myClass > myVector;
(The complete code can be seen here: http://codepad.org/iDD1Wme5 )
In this example I would like to be able to retrieve objects in the vector based on the "z" or "foo" members without having to write another 2 functions similar to "FindDataById".
Is that possible?
You can use a template and pointer to member.
typedef vector<myClass> myVector;
template<typename T>
bool FindDataById(const T &id, T myClass::* idMember, myClass &theClass,
const myVector &theVector)
{
for(myVector::const_iterator itr = theVector.begin(); itr != myVector.end();
++itr){
if((*itr).*idMember == id){
theClass = *itr;
return true;
}
return false;
}
Then call using, e.g.,
FindDataById(string("name"), &myClass::foo, theClass, theVector)
FindDataById(5, &myClass::x, theClass, theVector)
FindDataById(5.25f, &myClass::z, theClass, theVector)
Or, go with the find_if idea:
template<typename T>
struct Finder {
T val_;
T myClass::* idMember_;
Finder(T val, T myClass::* idMember) : val_(val), idMember_(idMember) {}
bool operator()(const myClass &obj) { return obj.*idMember_ == val_; }
};
And use:
find_if(theVector.begin(), theVector.end(), Finder<string>("name", &myClass::foo))
find_if(theVector.begin(), theVector.end(), Finder<int>(5, &myClass::x))
find_if(theVector.begin(), theVector.end(), Finder<float>(3.25f, &myClass::z))
See the answer of MSalters for a way to deduce the template argument automatically.
std::find_if has already been suggested, but without a code sample, so here's a more detailed version:
Define two functors to identify the object you're interested in:
struct z_equals {
z_equals(float z) : z(z) {}
bool operator()(const myClass& obj)
return z == obj.z;
}
float z;
};
struct foo_equals {
foo_equals(const std::string& foo) : foo(foo) {}
bool operator()(const myClass& obj)
return foo == obj.foo;
}
const std::string& foo;
};
And now, to search for elements where z == 42.0f, or foo == "hello world":
std::find_if(myVector.begin(), myVector.end(), z_equals(42.0f));
std::find_if(myVector.begin(), myVector.end(), foo_equals("hello world"));
You can use functors and pass it to your lookup method. That I mean is, define class which will overload bool operator( vectorElement element) and within this operator you will choose method how do you want to lookup the values.
template <typename T>
class ILookUp
{
bool operator( vector<T> elem)
{
if (elem == something)
return true;
false;
}
};
class VectorStorage
{
std::vector<Elements> lookup( ILookUp<Elements> lookup)
{
.....
if ( lookup(elem))
{
//add element to vector or whatever.
}
.....
return result;
}
.....
}
It might be worth taking a look at std::find defined in algorithm and boost::lambda
Without lambda's you'd need to write some predicates, or at least instantiate them:
template
struct member_select : public std::unary_function
{
T t;
T U::* m_u;
member_select(T const& t, T U::* m_u) : t(t), m_u(m_u) {}
bool operator()(U const& u) const { return u.*m_u == t; }
};
template
member_select make_member_select(T const& t, T U::* m_u)
{
return member_select(t, m_u);
}
Use: std::find_if(..., make_member_select("x", &myClass::foo));