Generic Class Library - bugs, description, questions, usage and suggestions - page 21

 
fxsaber:

We just need to overload GetHashCode for required type instead of starting IEqualityComparable.

In this case the ends go very far, and possible error will appear somewhere in the depths of the library. And then guess why some function is not found and whose fault it is. And interfaces guarantee in advance that all necessary functions are already defined in the object.

 
Alexey Navoykov:

In this case, the ends go very far, and the possible error occurs somewhere in the depths of the library. And then guess why some function is not found and whose fault it is. And interfaces guarantee in advance that all the necessary functions are already defined in the object.

Can you show an example for MqlTick?

 
Alexey Navoykov:

And interfaces guarantee in advance that all necessary functions are already defined in the object.

Yeah, except that these classes claim to be universal and should work for all types out of the box.

 
fxsaber:

Can you show me an example for MqlTick?

class CMqlTick : public IEqualityComparable<CMqlTick*>
{
 public: 
   MqlTick _tick;
   bool    Equals(CMqlTick* obj) { return obj!=NULL && obj._tick.time==_tick.time; }
   int     HashCode(void)        { return _tick.time; }
};
There's of course the costs of having to put in a class, plus the pointer check.
 
Alexey Navoykov:
There are costs here, of course, that we'll have to put in a class, plus pointer check.

Thank you, but I can not understand what is the advantage of this approach in practice?

In SB, the code is as follows

//+------------------------------------------------------------------+
//| Class CKeyValuePair<TKey, TValue>.                               |
//| Usage: Defines a key/value pair that can be set or retrieved.    |
//+------------------------------------------------------------------+
template<typename TKey,typename TValue>
class CKeyValuePair: public IComparable<CKeyValuePair<TKey,TValue>*>
  {
protected:
   TKey              m_key;
   TValue            m_value;

public:
                     CKeyValuePair(void)                                              {   }
                     CKeyValuePair(TKey key,TValue value): m_key(key), m_value(value) {   }
                    ~CKeyValuePair(void)                                              {   }
   //--- methods to access protected data
   TKey              Key(void)           { return(m_key);   }
   void              Key(TKey key)       { m_key=key;       }
   TValue            Value(void)         { return(m_value); }
   void              Value(TValue value) { m_value=value;   }
   //--- method to create clone of current instance
   CKeyValuePair<TKey,TValue>*Clone(void) { return new CKeyValuePair<TKey,TValue>(m_key,m_value); }
   //--- method to compare keys
   int               Compare(CKeyValuePair<TKey,TValue>*pair) { return ::Compare(m_key,pair.m_key); }
   //--- method for determining equality
   bool              Equals(CKeyValuePair<TKey,TValue>*pair) { return ::Equals(m_key,pair.m_key); }
   //--- method to calculate hash code   
   int               HashCode(void) { return ::GetHashCode(m_key); }

It turns out that the proposed dances only in order not to overload this GetHashCode. But is it worth the trouble in this case?

 
fxsaber:

Thank you, but I can not understand what is the advantage of this approach in practice?

In SB, the code is as follows

It turns out that the proposed dances only in order not to overload this GetHashCode. But is it worth the trouble in this case?

If speed is critical, then probably it's better to overload.

The point is that in .NET, where this library was ported from, all built-in types already have interfaces from the beginning. This is how int, aka Int32, is defined:

public struct Int32 : IComparable, IFormattable, IConvertible, 
        IComparable<int>, IEquatable<int>

That's why there's no overloading there.

And the CKeyValuePair class itself would be declared a little differently.

Although it would be better to spend this time on improving the functionality of the language. Then it would be enough to copy the entire .Net library and everything would work.

 
Alexey Navoykov:
There are costs here, of course, that you'll have to put in a class, plus pointer check.
What's the problem with putting this code into the GetHashCode overload? Then you don't need to inherit from the interface
 
Combinator:
What's the problem with shoving this code into the GetHashCode overload? then you don't need to inherit from the interface

It is possible, of course. But it complicates control over the process. Suppose you have a bunch of different GetHashCodes, scattered throughout the code, and which of them are called here (and where they are located), it can be difficult to understand. For example when calling a function, the argument casts to some other type. In C# this is probably why the template possibilities are very limited comparing to C++

 
Alexey Navoykov:

It is possible, of course. But it complicates the control of the process.

In C++ this interface is unnecessary, normal interaction is achieved by simple overloading of operator <, and this operator can be defined outside the CLASS.

I think it's much easier and laconic than to turn such constructions. but you need native support of overloading operator < outside the class.

And for built-in structures there is nothing but overloading GetHashCode, because the stub is horrible and inheritance is impossible. Inheritance from structure is a crutch solution, because when using standard functions you have to manually cast structure to user inheritor to make everything work as intended.
 
Combinator:

Inheritance from a structure is a crutch solution, because it forces you to manually cast the structure to a custom inheritor when using standard functions to make everything work as intended.

Apparently you don't mean inheritance, but wrapping from a class over a structure?

Actually, such "forcing" is also a disadvantage of MQL functionality, since there is no way to overload the cast operator, otherwise the class would easily be cast to the structure implicitly.

But nobody bothered... The development has been stagnant for 2 years, no improvements and innovations.

While developers themselves here complain about the lack of multiple interfaces and other features, but continue to eat a cactus.)

Reason: