Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Effective C++: Item 41 - confusion about Implicit interfaces

I am reading Effective C++, Item 41 with the title of "Understanding implicit interfaces and compile-time polymorphism", It give this example and next an explanation but I don't understand this part.

template<typename T>
void doProcessing(T& w)
{
     if (w.size() > 10 && w != someNastyWidget) {
     ...

..., T must support a size member function, ....., But this member function need not return an integral type. It need not even return a numeric type. For that matter, it need not even return a type for which operator > is defined! All it needs to do is return an object of some type x such that there is an operator > that can be called with and object of type x and an int ...

Could you please explain what it is about and give more examples?

like image 720
Arash Avatar asked Dec 13 '22 15:12

Arash


1 Answers

It means that the T::size() function can return anything which can be compared (using >) to an int value.


Lets look at three examples:

  1. Return an int:

    struct MyT
    {
        // Some stuff...
    
        int size()
        {
            return some_calculation_returning_int();
        }
    
        // Some more stuff...
    };
    
  2. Return an object which can be converted to an int:

    struct MySizeType
    {
        // Some stuff...
    
        operator int()
        {
            return some_calculation_returning_int();
        }
    
        // Some more stuff...
    };
    
    struct MyT
    {
        // Some stuff...
    
        MySizeType size()
        {
            return MySizeType();
        }
    
        // Some more stuff...
    };
    
  3. Return an object which can be compared with > to an int:

    struct MyOtherSizeType
    {
        // Some stuff...
    
        operator>(int other)
        {
            return some_calculation_returning_int() > other;
        }
    
        // Some more stuff...
    };
    
    struct MyT
    {
        // Some stuff...
    
        MyOtherSizeType size()
        {
            return MyOtherSizeType();
        }
    
        // Some more stuff...
    };
    

While it should be quite clear that the first variant can be used, the other two can also be used. That is because they, one way or another, returns something which can be compared to an int value.

If we "expand" the three variants:

  1. w.size() > 10 is simply like it is.

  2. w.size() > 10 will be w.size().operator int() > 10. Here the MySizeType::operator int() conversion function will be used to convert the MySizeType object to an int value that can be compared.

  3. w.size() > 10 will be w.size().operator>(10). Here the MyOtherType::operator>() function will be used for the comparison itself.

Reference

  1. operator overloading
  2. user-defined conversion
like image 68
Some programmer dude Avatar answered Dec 26 '22 00:12

Some programmer dude