Sign in to follow this  
raptorstrike

Existance of an operator

Recommended Posts

raptorstrike    181
I am working on a comparison class that takes two data types and a comparison identifier and uses this to return the boolean value produced by the comparison. The problem results when an operator between two given classes is not defined, this generates a compilation error (understandably) BUT even if that comparison is never made an error is still generated, undesired but still understandable. The comparison class takes two arbitrary class types as template parameters and creates the class from that data SO, my real question is: Is there a way to prevent the compiler from generating the statements (when a template is used to create a class) that use the undefined operators via preprocessing directives. Heres a quick example
enum Operator
{
    LESS = 1,
    LESS_EQUAL...
}


class Compare<class One, class Two>
{
    //somewhere later in class
    Compare(One &A, Two &B, Operator nOp) : Op(nOp), First(A), Second(B) {}; 
    bool result()
    {
        switch(Op)
        {
            case LESS:
                return One < Two;
            break;
            case LESS_EQUAL:
                return ...
            ...
        }
     }
}
here, if One < Two is undeclared, even if Op does not equal LESS an error is generated so is there any way I could omit that section of code when the template is generated based on weather the operator is not defined? NOTE: I know that from the looks of it my design doesn't make any sense (why use a class to do comparison... etc) but don't worry about the actual design (that was horribly mutilated for the sake of brevity) its the actual concept that counts. Here is an example of what my final goal would be
    bool result()
    {
        switch(Op)
        {
            #if less operator is defined
            case LESS:
                return One < Two;
            break;
            #endif

            #if less than or equal to operator is defined
            case LESS_EQUAL:
                return ...
            ...
        }
     }
What I'm asking may be completely impossible but thats what I'm here to find out thanks for your time [smile]

Share this post


Link to post
Share on other sites
Antheus    2409
The whole beauty of this is that you get compile-time error, keeping you from potential errors.

Bot Boost MPL should do the trick. You might need to define something else besides operator, a flag, an empty class, or something similar to serve as condition, but other than that, it should be possible.

The problem with this is that you lose some compile-time safety, and you can easily get into situations where your comparison won't be performed.

Of course, I think this would work:

template < class A, class B>
class Comparator
{
bool compare( const A &a, const B &b )
{
switch (op) {
case LESS : return a < b;
case MORE : return a > b;
}
}
};

template < >
class Comparator< std::string, std::string >
{
bool compare( const std::string &a, const std::string &b )
{
return false;
}
};



So, you partially specialize template for comparison of strings in which there is no comparison performed.

This way, you can explicitly turn off comparison for arbitrary types without modifying them, plus retain compile-time checks for other classes.

The overriden template that doesn't do anything should get compiled out completely.

Share this post


Link to post
Share on other sites
JohnBolton    1372
What about doing it this way:

template < typename One, typename Two, typename Op >
bool Compare( One const & A, Two const & B, Op const & C)
{
return C( A, B );
}
And you might use it like this:
    Foo a, b;
bool x = Compare( a, b, std::less<Foo> );

Share this post


Link to post
Share on other sites
Jaiminho    184
As JohnBolton pointed, a nice approach is done by using a function pointer. The function returns the bool state your operation would return and you can also make custom comparations, not simply the already operator defined ones.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this