Passing operator as a parameter
I want to have a function that evaluates 2 bool
vars (like a truth table).
For example:
Since
T | F : T
then
myfunc('t', 'f', ||); /*defined as: bool myfunc(char lv, char rv, ????)*/
should return true;
.
How can I pass the third parameter?
(I know is possible to pass it as a char* but then I will have to have another table to compare operator string and then do the operation which is something I would like to avoid)
Is it possible to pass an operator like开发者_运维知识库 ^
(XOR) or ||
(OR) or &&
(AND), etc to a function/method?
Declare:
template<class Func> bool myfunc(char lv, char rv, Func func);
Or if you need to link it separately:
bool myfunc(char lv, char rv, std::function<bool(bool,bool)> func);
Then you can call:
myfunc('t', 'f', std::logical_or<bool>());
@ybungalobill posted a C++ correct answer and you should stick to it. If you want to pass the operators, functions will not work, but macros would do the work:
#define MYFUNC(lv, rv, op) ....
// Call it like this
MYFUNC('t', 'f', ||);
Be careful, macros are evil.
What you can do is define proxy operators that return specific types.
namespace detail {
class or {
bool operator()(bool a, bool b) {
return a || b;
}
};
class and {
bool operator()(bool a, bool b) {
return a && b;
}
};
// etc
class X {
or operator||(X x) const { return or(); }
and operator&&(X x) const { return and(); }
};
};
const detail::X boolean;
template<typename T> bool myfunc(bool a, bool b, T t) {
return t(a, b);
}
// and/or
bool myfunc(bool a, bool b, std::function<bool (bool, bool)> func) {
return func(a, b);
}
// example
bool result = myfunc(a, b, boolean || boolean);
You can if desperate chain this effect using templates to pass complex logical expressions.
Also, the XOR operator is bitwise, not logical- although the difference is realistically nothing.
However, there's a reason that lambdas exist in C++0x and it's because this kind of thing flat out sucks in C++03.
In modern C++ can pass any operator by using lambdas.
Update 1: the proposed solution introduces small improvement which is suggested by @HolyBlackCat
#include <iostream>
template<class T, class F> void reveal_or(T a, T b, F f)
{
// using as function(a, b) instead of expression a || b is the same thing
if ( f(a, b) )
std::cout << a << " is || " << b << std::endl;
else
std::cout << a << " is not || " << b << std::endl;
}
template<class T> void reveal_or(T a, T b)
{
// reuse the already defined ||
reveal_or(a, b, [](T t1, T t2) {return t1 || t2; });
}
Don't bother how to pass parameter if || operator is defined
int main ()
{
reveal_or('1', 'a');
return 0;
}
Passing explicitly as parameter. We can pass anything, including including any exotic nonsense
int main ()
{
//same as above:
reveal_or('1', 'a', [](char t1, char t2) { return t1 || t2; });
//opposite of above
reveal_or('1', 'a', [](char t1, char t2) { return !( t1 || t2; ) });
return 0;
}
It's hard to be realized. In C++, function parameter need an memroy address to find its object, but operator is decided in compile time. Operator won't be a object. So you can think about MACRO to finish your task.
精彩评论