Что такое не шаблонные члены C ++, используемые в трюке Бартона-Нэкмана? - PullRequest
0 голосов
/ 19 мая 2009

Из википедии:

// 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
};

Предполагается, что это будет Бартон-Нэкман , который мог бы выполнить пространственный анализ во время компиляции (проверка того, что некоторые операции, применяемые к переменным, заканчиваются в сопоставимых числах, таких как скорость, сопоставимая с пространством / временем, но не ускорение).

Может ли кто-нибудь объяснить мне, как, или, по крайней мере, объяснить мне, что являются НЕШАБЛОННЫМИ членами?

Спасибо

Ответы [ 3 ]

4 голосов
/ 20 мая 2009

Правила языка изменились с момента изобретения паттерна, хотя были приняты меры, чтобы не нарушать его. Другими словами, насколько я могу судить, он все еще работает, но по другим причинам, чем изначально. Я не думаю, что я бы основывал попытку размерного анализа на этом паттерне, так как думаю, что сегодня есть лучшие способы сделать это.

Я также думаю, что пример слишком тривиален, чтобы быть полезным. Как уже говорилось, создание экземпляра equal_comparable<value_type> приводит к появлению operator== и operator!= для value_type. Поскольку они не являются членами, не имеет значения, что наследование является частным, они по-прежнему могут быть выбраны при разрешении вызова. Просто трудно понять смысл этого примера. Допустим, однако, что вы добавили параметр шаблона в equal_comparable и несколько других вещей:

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;
};

Отказ от ответственности: я понятия не имею, так ли это предполагается, что предполагается использовать, но я достаточно уверен, что это будет работать, как описано.

1 голос
/ 19 мая 2009

Создание экземпляра equal_comparable<value_type> в классе value_type заставляет компилятор генерировать две функции сравнения:

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); }

Эти функции не являются шаблонами, поскольку они не зависят от каких-либо параметров шаблона, но они также не являются членами, поскольку они объявлены как friend.

1 голос
/ 19 мая 2009

На самом деле это не шаблонные элементы - операторы сравнения в базовом шаблоне - они используются ADL для производного класса. Элемент шаблона будет выглядеть примерно так:


class C
{
    ...
    template < typename T > void DoGreatStuff( T t ) { ... }
    ...
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...