开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜