Перейти к содержанию
    

Растолкуйте по шаблону С++

Помогите, плиз, устранить пробел в знаниях. Что значит второе определение Set() в этом шаблоне?

 

template<class Regs>
class PortImplementation
{
  public:
    static void Set(uint16_t value)
    {
      Regs()->BSRR = value;
    }

    template<uint16_t value>
    static void Set()         //<--- ???
    {
      Regs()->BSRR = value;
    }
};

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

оптимизацию компилятора не учитываем

 

в первом случае будет создана функция, где регистр будет задан как "константа" (новый регистр - новая функция), а значение передаётся как параметр функции, т.е. на ассемблере будет производиться запись в регистр (вывода) из другого регистра (выводимое значение)

LD R2,55

LD R1,R2

 

во втором случае и регистр и значение будут "константами", т.е. на ассемблере будет записываться конкретное число в конкретный регистр

LD R1,55

 

возможно данный код служил для дополнительной оптимизации

Изменено пользователем technik-1017

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо, идея понятна, поэкспериментирую на досуге.

 

Перечитал всё про частичную специализацию шаблонов - ничего про это не нашёл.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Потому что это не частичная специализация. Это шаблонная функция в шаблонном классе. Т.е. вначале будет инстанцирован класс для всех используемых классов Регс, а потом в каждом будет дополнительно созданы методы для всех значений в угловых скобках. Автор этого надеялся на то что всё в итоге будет заинлайнено.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Это шаблонная функция в шаблонном классе.
Я не понимаю как в неё попадает параметр value и почему только константный. И почему функция а не метод?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

метод=функция определенная в классе.

Попадает он из места вызова:

PortImplementation<some_chip_regs_type> some_chip_port;

some_chip_port.Set<0>();

 

В результате в коде, без оптимизаций появляются (если без манглинка) две функции:

PortImplementation<some_chip_regs_type>::Set(uint16_t value);

и

PortImplementation<some_chip_regs_type>::Set<0>();

 

Обратите внимание что они статические т.е. класс по сути является неймспейсом для этих функций и ничем более.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

То есть, я сам константный вызов должен сделать, а не компилятор догадается? Тогда почти совсем понятно. Осталось только с компилятором поработать, чтобы прочувствовать до конца. Думается, что в данном случае компилятор получив константу на вход нешаблонного метода всё оптимизирует не хуже.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Функция, объявленная внутри класса и являющаяся нестатической == функция-член.

Виртуальная функция-член == метод.

 

В примере определены статические функции-члены шаблонного класса, одна из которых является шаблонной. Статические функции-члены по смыслу являются обычными функциями с той разницей, что имеют доступ к представлению класса. В примере определены перегруженные функции. Одна обычная - получает аргумент, вторая - по сути даёт множество функций в зависимости от параметра её шаблона. Разницу в кодогенерации показали выше. Что лучше подходит в том или ином случае, решать как всегда автору.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

dxp, Спасибо. "Кто ясно мыслит, тот ясно излагает."© А. Шопенгауэр

 

Поигрался с компилятором - на простых примерах оптимизатор сводит разницу на нет. Но в целом идея понятна.

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Поигрался с компилятором - на простых примерах оптимизатор сводит разницу на нет. Но в целом идея понятна.

Да, так и должно быть - хороший компилятор, если видит все начальные условия, может (да, по-хорошему, и должен) сгенерировать оптимальную реализацию на этапе компиляции. В приведённом примере это должны быть просто инструкции загрузки регистра в обоих случаях (если компилятор видит значение аргумента функции).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Виртуальная функция-член == метод.

А вы сможете подтвердить это пунктом стандарта? Я вот сейчас поискал из любопытства - вдруг позабывал всё и не нашел.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я думаю, что термин "метод" начали применять в нашей литературе, чтобы немного облагородить ругательство "функция-член". Тем более, он хорошо описывает назначение функций-членов.

 

По версии мелкомягких члены класса это

Ниже приведен полный список категорий членов.

- Специальные функции-члены.

 

- Функции-члены.

 

- Элементы данных, включая встроенные типы и другие пользовательские типы.

 

- Операторы

 

- Объявления вложенных классов

 

- Объединения

 

- Перечисления.

 

- Битовые поля.

 

- Дружественные объекты.

 

- Псевдонимы и определения типов.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А вы сможете подтвердить это пунктом стандарта? Я вот сейчас поискал из любопытства - вдруг позабывал всё и не нашел.

Я ждал этого вопроса. :)

 

В стандарте С++ вообще нет термина "метод". Но зато этот термин без разбора применяют как псевдоним термина "функция-член" - очевидно потому, что это короче. Между тем, термин "метод" взят из объектно-ориентированных языков, где все объекты существуют в иерархиях и все их функции-члены по сути являются виртуальными, поэтому и являются методами. Смысл этого очень простой: когда у вас иерархия объектов, то при наследовании классы-потомки имеют "по наследству" весь набор функций-членов предков, но при этом в потоках сами эти функции могут быть перекрыты - т.е. заменены на свои, классический пример - иерархия классов геометрических фигур:

 

Figure 
    Circle
    Triangle
    Rectangle

 

В базовом классе есть функция-член draw(), она же по наследству попадает и в потомки. Например, функция по умолчанию умеет рисовать линии по точкам, и это хорошо подходит для треугольника и прямоугольника, но не подходит для окружности, поэтому для окружности эту функцию перекрыли - написали свою. Ясно, что и для других фигур тоже можно переписать для каждой по-своему, если это требуется. Получается, что у разных фигур разные способы нарисовать себя - свои методы сделать это!

 

Далее, есть сцена, на которой фигуры, и чтобы их все нарисовать, достаточно пройти по массиву указателей на них, вызвав функцию-член draw() - каждая фигура будет нарисована своим, подходящим ей способом - методом.

 

В реальности ровно эта задача встаёт при реализации GUI - там все виджеты сами отрисовывают себя своим способом - методом.

 

Вот и получается, что в чистых ОО языках все функции-члены классов всегда являются методами [выполнить действия своим способом, отличным от других методом], т.е. по сути "метод" - синоним слова "способ".

 

Теперь когда мы переходим к С++, который не является чистым ОО языком, а является гибридным языком, поддерживающим разные парадигмы программирования: процедурную, объектную, объектно-ориентированную, то очевидно, что далеко не все функции-члены классов являются именно методами, а только те, которые несут смысл, представленный выше. А это относится только к ОО части С++, т.е. к иерархиям наследования и их виртуальным функциям-членам, которые, безусловно, являются методами.

 

В книге автора языка Б. Страуструпа есть фраза: "Иногда виртуальные функции-члены называют методами".

 

Относиться к ситуации можно по-разному, и много людей просто кладут на аргументацию и не дают себе труда ни разобраться, ни следовать этому - для них "метод" просто удобнее, потому что короче. Кто-то просто не в курсе дела, а в книжках и на форумах пишут "метод", вот они и повторяют. Но я считаю, что терминологическая точность должна быть, иначе начинает теряться просто смысл терминологии, поэтому лучше не лениться и называть вещи правильно.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

dxp, знаете, меня и Kabdim (мы с ним не только учились в одном институте, но, похоже, и работали в одном месте когда-то) так в институте учили.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

чтобы немного облагородить ругательство "функция-член".

Да кмк здесь слово метод более употребительно чем там, но и там оно тоже используется.

Вопрос на самом деле неоднозначный. Вот к примеру есть PPP Style Guide, в котором Страуструп пишет на 9 странице:

Not every member function (”method”) should be virtual and by default they are not

Из-за чего так? Кмк потому что методы вошли в общепринятую терминологию позже плюсов. К тому же вошли в двух разных школах. В ораклово-явовской метод=вирутальная функция член, в майкрософто-решеточной (и дельфевской из которой решетка переняла многое) метод просто функция в классе. Поэтому прошу не утверждать что есть единая верная интерпретация. Вообще в оригинале абстрактного ОО (Smalltalk) метод диспетчеризуется по имени, о чем (и вообще о философии ОО применительно к плюсам) Страуструп рассуждает в What is ‘‘Object-Oriented Programming’’ - рекомендую прочитать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...