Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Растолкуйте по шаблону С++
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Cредства разработки для МК
VladislavS
Помогите, плиз, устранить пробел в знаниях. Что значит второе определение 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;
    }
};
technik-1017
оптимизацию компилятора не учитываем

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

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

возможно данный код служил для дополнительной оптимизации
VladislavS
Спасибо, идея понятна, поэкспериментирую на досуге.

Перечитал всё про частичную специализацию шаблонов - ничего про это не нашёл.
Kabdim
Потому что это не частичная специализация. Это шаблонная функция в шаблонном классе. Т.е. вначале будет инстанцирован класс для всех используемых классов Регс, а потом в каждом будет дополнительно созданы методы для всех значений в угловых скобках. Автор этого надеялся на то что всё в итоге будет заинлайнено.
VladislavS
Цитата(Kabdim @ Jul 24 2018, 16:50) *
Это шаблонная функция в шаблонном классе.
Я не понимаю как в неё попадает параметр value и почему только константный. И почему функция а не метод?
Kabdim
метод=функция определенная в классе.
Попадает он из места вызова:
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>();

Обратите внимание что они статические т.е. класс по сути является неймспейсом для этих функций и ничем более.
VladislavS
То есть, я сам константный вызов должен сделать, а не компилятор догадается? Тогда почти совсем понятно. Осталось только с компилятором поработать, чтобы прочувствовать до конца. Думается, что в данном случае компилятор получив константу на вход нешаблонного метода всё оптимизирует не хуже.
dxp
Функция, объявленная внутри класса и являющаяся нестатической == функция-член.
Виртуальная функция-член == метод.

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

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

dxp
Цитата(VladislavS @ Jul 25 2018, 09:52) *
Поигрался с компилятором - на простых примерах оптимизатор сводит разницу на нет. Но в целом идея понятна.

Да, так и должно быть - хороший компилятор, если видит все начальные условия, может (да, по-хорошему, и должен) сгенерировать оптимальную реализацию на этапе компиляции. В приведённом примере это должны быть просто инструкции загрузки регистра в обоих случаях (если компилятор видит значение аргумента функции).
Kabdim
Цитата(dxp @ Jul 25 2018, 05:15) *
Виртуальная функция-член == метод.

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

По версии мелкомягких члены класса это
Цитата
Ниже приведен полный список категорий членов.
- Специальные функции-члены.

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

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

- Операторы

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

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

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

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

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

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

dxp
Цитата(Kabdim @ Jul 26 2018, 16:24) *
А вы сможете подтвердить это пунктом стандарта? Я вот сейчас поискал из любопытства - вдруг позабывал всё и не нашел.

Я ждал этого вопроса. sm.gif

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

Код
Figure
    Circle
    Triangle
    Rectangle


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

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

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

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

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

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

Относиться к ситуации можно по-разному, и много людей просто кладут на аргументацию и не дают себе труда ни разобраться, ни следовать этому - для них "метод" просто удобнее, потому что короче. Кто-то просто не в курсе дела, а в книжках и на форумах пишут "метод", вот они и повторяют. Но я считаю, что терминологическая точность должна быть, иначе начинает теряться просто смысл терминологии, поэтому лучше не лениться и называть вещи правильно.
VladislavS
dxp, знаете, меня и Kabdim (мы с ним не только учились в одном институте, но, похоже, и работали в одном месте когда-то) так в институте учили.
Kabdim
Цитата(VladislavS @ Jul 26 2018, 12:43) *
чтобы немного облагородить ругательство "функция-член".

Да кмк здесь слово метод более употребительно чем там, но и там оно тоже используется.
Цитата(dxp @ Jul 26 2018, 13:22) *

Вопрос на самом деле неоднозначный. Вот к примеру есть PPP Style Guide, в котором Страуструп пишет на 9 странице:
Цитата
Not every member function (”method”) should be virtual and by default they are not

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

Я вижу, вам тоже оно нравится (более коротко и/или привыкли).

Цитата(Kabdim @ Jul 27 2018, 16:15) *
Из-за чего так? Кмк потому что методы вошли в общепринятую терминологию позже плюсов.

"Метод" (как и ООП) появился куда раньше плюсов. Обратите внимание, он говорит про Java и взял в кавычки, подчёркивая, что в плюсах далеко не все функции-члены являются методами.

Цитата(Kabdim @ Jul 27 2018, 16:15) *
К тому же вошли в двух разных школах. В ораклово-явовской метод=вирутальная функция член, в майкрософто-решеточной (и дельфевской из которой решетка переняла многое) метод просто функция в классе. Поэтому прошу не утверждать что есть единая верная интерпретация.

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

Цитата(Kabdim @ Jul 27 2018, 16:15) *
Вообще в оригинале абстрактного ОО (Smalltalk) метод диспетчеризуется по имени, о чем (и вообще о философии ОО применительно к плюсам) Страуструп рассуждает в What is ‘‘Object-Oriented Programming’’ - рекомендую прочитать.

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

Цитата
This idea captures only part of the expressive
power of inheritance, but it is strongly encouraged by languages where every member function is virtual
(or a method)
.
Kabdim
Цитата(dxp @ Jul 27 2018, 13:05) *
"Метод" (как и ООП) появился куда раньше плюсов. Обратите внимание, он говорит про Java и взял в кавычки, подчёркивая, что в плюсах далеко не все функции-члены являются методами.

"Метод" как способ диспатча по строке с именем - да, но не то что вы сейчас называете методом. Почему вы из кавычек умудрились вытянуть этот скрытый смысл? Для меня кавычки это цитата, не более того. Которые в данном месте применили что бы подчеркнуть что это не официальный термин плюсов, а джавовский.
Цитата(dxp @ Jul 27 2018, 13:05) *
На последнюю можно отмапить термин "метод", переходя на ОО терминологию.

Ну раз её можно "мапить", то почему бы не отмапить в шарпнутую плоскость?
Цитата(dxp @ Jul 27 2018, 13:05) *
Вот если вы пройдёте по вхождениям словам "method", то убедитесь, что Страуструп очень аккуратно использует терминологию, употребляя этот термин именно как синоним виртуальной функции-члена, например (стр. 20):

Собственно я и не спорил что Страуструп использует слово метод и в том и в другом смысле. Но из пропузалов в стандарт слово метод вымарывается нещадно и в значении витруальной функции члена тоже. Последнее несложно увидеть в репозиториях пропоузалов.
halfdoom
Видимо не стоит буквально переводить "method" как "метод". В русском языке слово "метод" в контексте класса/объекта устаканилось для обозначения статической/виртуальной/обычной функции или процедуры, вложенной в контекст класса. В англоязычных источниках, используется member function, который, как уже заметили, несколько не благозвучен в буквальном переводе.
dxp
Цитата(halfdoom @ Jul 27 2018, 17:59) *
Видимо не стоит буквально переводить "method" как "метод". В русском языке слово "метод" в контексте класса/объекта устаканилось для обозначения статической/виртуальной/обычной функции или процедуры, вложенной в контекст класса.

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

Цитата(halfdoom @ Jul 27 2018, 17:59) *
В англоязычных источниках, используется member function

Полагаю, это потому, что они построже обращаются с терминологией.

Цитата(halfdoom @ Jul 27 2018, 17:59) *
который, как уже заметили, несколько не благозвучен в буквальном переводе.

Хе. Ну, тогда и для членов-данных нужно тем более придумать левый синоним - ведь с данными-то всё ещё хуже (если там хоть функция-ч..., то данные чаще всего называют просто ч...). laughing.gif
halfdoom
Цитата(dxp @ Jul 27 2018, 14:19) *
обычные функции уже называют методами, то мне тогда совсем не понятно, почему именно методами


Имееются в виду не статические или виртуальные:

Код
class A
{
  void plain_method();
};


Цитата(dxp @ Jul 27 2018, 14:19) *
Ну, тогда и для членов-данных нужно тем более придумать левый синоним - ведь с данными-то всё ещё хуже


Так их вроде так и называют — "(статические) данные класса".

Вот со свойствами из ОО-Паскаля или С-шарпа вышла накладка, т.к. понятие "свойства класса" выходит за рамки внутриклассовых синтаксических конструкций. В начале 90-х, некоторые придерживались кальки с английского "проперти", что в беглой речи тоже превращало property editor в не очень благозвучное слово.
dxp
Цитата(halfdoom @ Jul 27 2018, 19:00) *
Так их вроде так и называют — "(статические) данные класса".

Что-то вы совсем не о том. Члены-данные класса (class data member) и статические члены-данные класса - это две ба-альшие разницы.
halfdoom
Цитата(dxp @ Jul 27 2018, 16:02) *
Что-то вы совсем не о том. Члены-данные класса (class data member) и статические члены-данные класса - это две ба-альшие разницы.


Просто сокращенно написал, понятно, что два разных вида:

- данные класса;
- статические данные класса.

Forger
Вставлю свои "пять копеек"
Я использую только два термина для класса:
функции-члены (любые) - "методы",
данные (тоже любые) - "поля": https://ru.wikipedia.org/wiki/%D0%9F%D0%BE%...%81%D1%81%D0%B0
Не помню, где это это вычитал, но зацепила простота и краткость этих двух слов. Привык sm.gif

Есть еще третий термин "свойство", но не использую его, поскольку, по-моему, оно это слишком уже не очевидное - где-то им называют поля класса, а где - сеттеры/геттеры. Можно запутаться.

Не вижу смысла в тексте указывать вид "метода" или "поля" - статические/нестатические/виртуальные/закрытые/защищенные ... - это, имхо, лишнее, и не имеет как такового смысла в рядовом общении.
Термин "функция" использую применительно только к си, равно как и "процедура" - к паскалю (дельфи).
dxp
Ещё был случай в истории, когда в строевой подготовке использовали "термины": "сено" и "солома". Для простоты. Многим очень нравилась простота и краткость этих двух слов.
Forger
Цитата(dxp @ Aug 9 2018, 04:20) *
Ещё был случай в истории, когда в строевой подготовке использовали "термины": "сено" и "солома". Для простоты. Многим очень нравилась простота и краткость этих двух слов.

Ну и по "традиции жанра" наверняка нашелся тот, который был против этой "простоты". Разумеется, ему дали "три наряда вне очереди"? ... :D
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.