55:28 можно привести такой пример частичной специализации по nontype параметру. Если мы решаем задачу механики, то момент в 3D пространстве будет является тензором 1 ранга (вектор размера dim), а в 2D пространстве это момент вырождается в скаляр. Тогда можно использовать такой шаблон: template struct Moment {}; template struct Moment { typedef Number type; static constexpr unsigned int size = 1; }; template struct Moment { typedef Tensor type; static constexpr unsigned int size = 3; };
Здраствуйте. Вопрос к блоку 12:35 - 21:03, разве публично наследуя Wrapper, мы не оставляем классу Device пользоваться теми же перегрузками operator()? И на 19:59 не будет ли достаточно перемещающего оператора присваивания?
Но ведь 57:30 в реальности так нельзя делать. Количество шаблонных аргументов должно совпадать в примари шаблоне и специализации. Опять скажу, что проблема в терминологии "откусывания", которая тут не подходит, на самом деле мы просто объявляем аргументы от которых зависит специализация, то есть не "откусываем T" а "допустим, есть T и U и шаблонные аргументы vector, vector"
Опечатка на слайде. Я имел в виду нечто вот такое: godbolt.org/z/zGf18znaE Но случайно оставил два параметра в primary template. Я даже словами сказал что у специализации больше параметров а на слайде их столько же =) Время до нахождения ошибки -- буквально меньше часа от выкладки. Спасибо за внимательность, добавлю в errata
20:04 А чем это вообще мотивировано (если это понятно из предыдущей лекции, прошу прощения, я её пропустил)? Для меня класс Wrapper похож на shared_ptr, так почему изначально созданные объекты Wrapper не обладают счетчиком 1, но вместо этого мы сами выбираем изначально 0 или 1? Получается, что wrapper не инкапсулирует счетчик, и его можно дергать где-то снаружи? Зачем Wrapper тогда вообще? Просто не понимая, это выглядит как-то неправильно
Константин, спасибо за прекрасную лекцию. Возникло несколько вопросов. На 37:50 вы говорите об удалении специализации. А насколько это хорошая практика - удалять общий шаблон для функции и определять только валидные специализации? Почему специализации шаблонных функций можно удалять, а шаблонных классов нет? Видимо это решается концептами, но до ваших лекций по концептам я еще не дошел.
Удалять общий шаблон и оставлять только специализации это не то чтобы хорошая или плохая практика, так просто нельзя делать. Вы можете не написать тела для общего шаблона, но это не удаление, это вы вызываете ошибку инстанцирования. Специализации шаблонов классов в некотором смысле можно "удалять" -- объявите её с приватным конструктором например. Для этого просто нет приятного синтаксиса. Почему нет я не знаю, мб не ввели.
35:32 Константин, а может так случится, что в двух заголовочных файлах размещены перегруженные шаблоны, и в одном из них так же есть явная специализация, но после подключения этих файлов явная специализация меняет соответствие? Если да, то как от такого защищаться?
Здравствуйте, Константин Как всегда замечательно. Подскажите пожалуйста, по аналогии с запрещением инстанцирования функций для определённых параметров, можно запрещать инстанцирование класса для определённых параметров и/или частичное инстанцирование?
Присваивание копированием делает retain, я же показывал код: github.com/KhronosGroup/OpenCL-CLHPP/blob/61a5c9afcd8f2fcbfdf49bb4504036cc679f8c3d/include/CL/opencl.hpp#L1874 Move-ctor там есть, он в данном случае не помогает. Проблема этого кода в том, что если вы не сделали retain в конструкторе, у вас в любом случае при правильной работе будет на один release больше. Тут никак иначе не выкрутиться.
На видео проблема возникает в цикле, когда временный объект Device присваивается объекту в векторе. Разве здесь не может быть задействован оператор присваивания перемещением у Device? Тогда он просто переместил бы временный объект в объект вектора и все.
И то и другое сделано: github.com/KhronosGroup/OpenCL-CLHPP/blob/61a5c9afcd8f2fcbfdf49bb4504036cc679f8c3d/include/CL/opencl.hpp#L1896 Но не помогает в данном случае.
19:38 говорится что Device сделает release, когда умрет. Но Wrapper& operator = (Wrapper&& rhs) обнуляет rhs.object_. Тогда в диструкторе rhs не будет release, разве нет? тогда не понимаю зачем нужен допонительный +1 retain