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

    

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

Помогите, плиз, устранить пробел в знаниях. Что значит второе определение 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’’ - рекомендую прочитать.

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


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

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти