Войти
ПрограммированиеФорумОбщее

Типизированные int'ы (3 стр)

Страницы: 1 2 3 4 59 Следующая »
#30
(Правка: 20:40) 20:40, 13 июля 2019

Suslik
> а хранить raw pointer'ы на что попало — не моветон?
Нет, не моветон. Допустим у тебя есть класс A, который ссылается на класс B*. Если у тебя by design классы A сливаются до классов B, то хранить сырой указатель не моветон. Если класс B может сливаться в произвольный момент времени, то тут 2 варианта:
1. Нотификации или ручная чистка указателей на B*
2. Слабые ссылки, например weak_ptr или его аналоги

А завязывать логику на контейнер типа X считаю неправильным. Сегодня тебе там нужен vector, а завтра ты понимаешь, что нужно уже OctTree, а вектор как бы уже не выкинешь. И приходится поддерживать 2 контейнера. В особо тяжелых случаях в OctTree хранят индексы на элементы из vector-а.

> да и мало ли существует ситуаций, где указатели применять нельзя? —
> сериализация
Для сериализации указатели отлично применяются. Проходишь по объектам, индексируешь, записываешь индексы. Индексация за линейное время в std::unordered_map<MyObject*, int>

> шейдеры
Если ты напишешь свой аллокатор памяти в шейдере, то индекс в буфере фактически и будет являтся "указателем". Просто шейдерный язык пока еще в зачаточном состоянии, поэтому там нет указателей как таковых. Приходится выкручиваться тем что есть.

> индексы — это только частный случай. в общем случае величины, хранящие разные
> по смыслу переменные, нет смысла присваивать друг другу, даже если они
> формально одного типа
Вот тут я с тобой согласен. В плюсах не хватает конструкции, которая есть в том же Delphi. В Delphi можно написать так:

type
  TMyNewSuperType = type of Integer;
тут type of выводит новый тип из Integer, который не совместим с Integer. То есть сделать вот так уже нельзя:
var i: Integer;
    myInt: TMyNewSuperType;
begin
  i := myInt;
end;
Ну и так можно сделать с любым типом, а не только с Integer. Можно даже со своим классом такое провернуть:
  TMyNewClass = type of TMyOtherClass;

> не смысла ширине окна присвоить левел персонажа, хотя оба — инты. такой код не
> должен компилиться.
Тут тоже согласен. Тоже не понимаю, почему в плюсы в 2019 году до сих пор не ввели выведение типов.

Можно попутно кинуть камень в огород плюсов за то, что в них нет конструкции вида:

enum class ColorEnum{Red, Green, Blue};
const vec4 ColorValues[ColorEnum] = { {1,0,0,1}, {0,1,0,1}, {0,0,1,1} };
В 2019 году приходится для таких вот штук городить касты через int-ы. Добавлять в конец enum-а какой то Count.

#31
(Правка: 21:05) 20:56, 13 июля 2019

MrShoor
> В плюсах не хватает конструкции, которая есть в том же Delphi. В Delphi можно написать так:

> type
> TMyNewSuperType = type of Integer;
надо же, а в FPC это не прокатывает. Странно

понятно, они её до сих пор не смогли документировать.
"type of" остаётся фичей, а не официальным функционалом.

#32
21:08, 13 июля 2019

skalogryz
> надо же, а в FPC это не прокатывает. Странно
Да, есть такое. Причем даже если поставить {$mode delphi}. FPC просто не знает такой конструкции как type of.
Вообще в делфи есть 3 способа объявить новый NameType

TMyType = TMyOtherType;
обычный алиас. TMyType - просто замена слова для TMyOtherType
В случае с:
TMyType = type TMyOtherType;
Получаем уже выведение типа, а не алиас. TMyType совместим с TMyOtherType, то есть их можно присваивать друг другу. Но TMyType теперь является самостоятельным типом и данные на него можно найти в RTTI.
Ну и в случае с:
TMyType = type of TMyOtherType;
Мы выводим новый тип, и получаем подмножество. Теперь в переменную TMyType можно присвоить TMyOtherType, а наоборот уже нельзя.
#33
21:09, 13 июля 2019

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

#34
21:58, 13 июля 2019

Suslik
> Вроде бы в коде всё хорошо, он компилируется, только выдаёт полную ерунду или
> падает. Причина — в прототипе функции аргументы объявлены в другом порядке:
>
> float GetTotalDamage(int shipIndex, int asteroidIndex);
Потому что сигнатура должна быть

floa GetTotalDamage(const Ship& ship, const Asteriod& asteroid);
Не надо никуда никакие индексы передавать. Индекс - это вообще исключительно локальная сущность.

MrShoor
> новый тип из Integer, который не совместим с Integer
Ну, да, примитивный тип нельзя, но можно класс.

#35
5:18, 14 июля 2019

видос прямо по теме:


имеет смысл хотя бы послушать самое начало про motivation, потому что он лучше меня рассказывает, почему это полезно.

#36
(Правка: 5:37) 5:37, 14 июля 2019

и ещё классная идея по реализации: https://www.fluentcpp.com/2018/04/06/strong-types-by-struct/

struct Width { double asDouble; };

void foo()
{
    Width width {42};
    auto d = width.asDouble;
}
то есть суть в том, что конверсия к обёрнутому типу выполняется посредством поля asDouble — что по сути представляет простейший возможный интерфейс доступа. по-моему, интересный подход.
#37
(Правка: 6:36) 6:35, 14 июля 2019

Suslik
> и ещё классная идея по реализации
Это же очевидно.
Вопрос в том как сделать это без asDouble в С++ с его "неявной" типизацией и дибильными ограничениями.
Сам парился с этим сотнитыщраз, причем в контексте того же вулкана.

А вообще это банальная банальщина, которая сводиться к возможности наследования своего класса от int с последующим запретом на неявное приведение к int.
Но в С++ так нельзя, потому что дибильный автор языка не додумался до такого и огородил примитивы от классов.
А еще бесит что такая банальная и простая вещь обрастает каким-то хипстерским названием "strong typedefs". Теперь любой пук которые С++ не может с коробки будет иметь собственное имя?

#38
6:39, 14 июля 2019

Suslik#36
кстати, такое даже в glsl можно делать

#version 450
#extension GL_ARB_separate_shader_objects : enable

layout(location = 0) out vec4 outColor;

struct ShipIndex
{
  int asInt;
};
struct AsteroidIndex
{
  int asInt;
};
float GetTotalDamage(ShipIndex ship, AsteroidIndex asteroid) {return 0;}
void main()
{
  ShipIndex ship = {42};
  AsteroidIndex asteroid = {-1};
  outColor = vec4(GetTotalDamage(ship, asteroid));
}
попробую несколько шейдеров для эксперимента в таком стиле пописать.
#39
(Правка: 6:52) 6:52, 14 июля 2019

Great V.
> Но в С++ так нельзя, потому что дибильный автор языка не додумался до такого и
> огородил примитивы от классов.
он сейчас как раз типизацию к int-ам (простым типам) прикручивает.
чтобы можно было дюймы от сантиметров отличать.

#40
6:55, 14 июля 2019

skalogryz
откуда инфа?

#41
(Правка: 7:22) 7:22, 14 июля 2019

Suslik
> откуда инфа?
от Самого! он об этом говорил в одной из своих лекций про Ц++. (те что на CppCon канале)
но я пробежался по 4м из них и найти не могу :(

#42
12:09, 14 июля 2019

Это ж чуть ли не первая глава Effective c++ и влажная мечта Фюрера, как уже упомянули (толк еще времен принятия с++11 на channel9). Упоротость же, очевидно. Потом понадобится кастовать (мана кончится, ясен пень) и багов в этом борделе только увеличится. Операции надо на сэтах делать, а не делить по условным объектам.

#43
15:19, 14 июля 2019

Suslik
> Поэтому первый шаг — ввести различные типы для различных индексов, чтобы
> визуально их разграничить:
Я некогда уже спекулировал вокруг сходной идеи и её доведения до логического завершения.

> однако, для этого даже существуют реализованные кем-то библиотеки!
Ы. И как раз тоже 2 года назад.

using Width = NamedType<double, struct WidthTag>;
Форвард-объявление структуры прямо в шаблоне, который по ней инстанцируется? Эт чо, так можно было? 0_о
Если так, то можно ведь прямо даже почти до моей идеи допилить просто макросами. Вроде:
DEFTYPE(X, int);
DEFTYPE(Z, int);

X ReturnsX (DEFVAR(Z))
{
 DEFVAR(X) = (X)((int)VAR(Z) + 1);
 return VAR(X);
}
#44
20:08, 14 июля 2019

Great V.
> Вопрос в том как сделать это без asDouble
Great V.
> запретом на неявное приведение к int
Так, не понял. Можно подробнее? Доступ через asDouble - не то, доступ без asDouble - тоже не то. Бывает ещё какой-то способ?

Страницы: 1 2 3 4 59 Следующая »
ПрограммированиеФорумОбщее