What are the non-templated C ++ members used in the Barton-Nackman trick?

From Wikipedia:

// A class template to express an equality comparison interface.
template<typename T> class equal_comparable
{
    friend bool operator==(T const &a, T const &b) { return  a.equal_to(b); }
    friend bool operator!=(T const &a, T const &b) { return !a.equal_to(b); }
};

class value_type
// Class value_type wants to have == and !=, so it derives from
// equal_comparable with itself as argument (which is the CRTP).
     : private equal_comparable<value_type>
{
public:
    bool equal_to(value_type const& rhs) const; // to be defined
};

      

It is assumed to be Barton-Nackman , which may lead to compile-time sizing analysis (checking if some operations on variables will be performed in comparable quantities, such as speed comparable to space / time, but no acceleration).

Can anyone explain to me how, or at least explain to me what the NON-TEMPLATE members are?

thanks

0


a source to share


3 answers


The rules of the language have changed since the pattern was invented, although care was taken not to break it. In other words, as far as I can tell, it still works, but for different reasons than it originally did. I don't think I will base my dimension analysis on this pattern as I think there are better ways to do it today.

I also find this example too trivial to be useful. As already stated, the instance equal_comparable<value_type>

calls for operator==

and operator!=

for value_type

. Since they are not members, it doesn't matter that inheritance is confidential, they are still a good choice when resolving a call. In this example, it's just hard to get the point. Let's say, however, that you add a template parameter to equal_comparable

and a few more things:



template<typename U, typename V> class equal_comparable
{
    friend bool operator==(U const &a, V const &b) { return  a.equal_to(b); }
    friend bool operator!=(U const &a, V const &b) { return !a.equal_to(b); }
};

class some_other_type 
{
    bool equal_to(value_type const& rhs) const;
};

class value_type
: private equal_comparable<value_type>,      // value_type comparable to itself
  private equal_comparable<some_other_type>  // value_type comparable to some_other_type
{
public:
    bool equal_to(value_type const& rhs) const;
    bool equal_to(some_other_type const& rhs) const;
};

      

Disclaimer: I have no idea if this is how it should be, but I'm pretty sure it will work as described.

+4


a source


These are actually nontemplate nonmembers - comparison operators in the base template - they are used by ADL for the derived class. The template element would be something like:




class C
{
    ...
    template < typename T > void DoGreatStuff( T t ) { ... }
    ...
};

      

+1


a source


Instantiating the class equal_comparable<value_type>

in value_type

makes the compiler generate two comparison functions:

friend bool operator==(value_type const &a, value_type const &b) { return  a.equal_to(b); }
friend bool operator!=(value_type const &a, value_type const &b) { return !a.equal_to(b); }

      

These functions are not templates as they do not depend on any template parameter, but they are also non-members as they are declared as friend

.

+1


a source







All Articles