Здравствуйте, DenProg, Вы писали:
DP>Привет. Есть два типа определенные одинаково:
Сейчас это один тип
DP>Возможно ли сделать так, чтобы такое не компилилось, или хотя бы компилилось с предупреждением?
Тут уже посоветовали наследоваться от вектора. Имхо, это плохая идея, так как она может в некоторых местах протечь (где-нибудь перепутать пользовательский тип и сырой вектор — в ту или другую сторону).
Я бы предложил не морочить себе голову, а просто завернуть в структуру.
Пусть даже с публичным полем, — чтобы минимально возиться с вопросами, что надо от вектора, а что не надо. Потом при случае отрефакторить, благо, все точки использования хорошо видны (поиском по имени поля либо кровавым рефакторингом — сделать приватным и смотреть, где компиляция сломалась).
Здравствуйте, kov_serg, Вы писали:
S>>Это запросто могут быть координаты в многомерном пространстве. _>Это уже не id а набор признаков
В проекте, которому сейчас помогаю, как раз объекты однозначно идентифицируются координатами в N-мерном пространстве. И это именно что полный аналог Id, а не набор признаков.
S>>И запросто может быть так, что количество измерений в этом пространстве определяется динамически и неизвестно на этапе компиляции, поэтому и std::vector, а не std::array.
_>Дело не в этом. Id предполагает хотя бы сравнение этих самых id
Здравствуйте, ·, Вы писали:
·>Не надо так делать. Лучше так:
Обоснование будет какое-нибудь?
·> // методы, имеющие смысл для id, а не вся простыня вектора
А почему ты уверен, что не вся простыня вектора имеет смысл для ID? Если человек выбрал вектор для задания собственных типов, то, возможно, ему и нужна вся "простыня"?
--
Справедливость выше закона. А человечность выше справедливости.
Здравствуйте, kov_serg, Вы писали:
R>>Почему только число? А строка может быть? _>Потому что из простых соображений на практике достаточно int32 или int64 для распределённых систем guid(int128)
И кроме того, подумалось. Ведь главный вопрос этой темы можно было бы без труда переформулировать и для чисел:
typedef int ElementId;
typedef int LogicalId;
void func(ElementId&); // <- ???
Так что, вопрос можно ли использовать вектор для задания ID, или нельзя — это вообще оффтоп в данном случае.
--
Справедливость выше закона. А человечность выше справедливости.
Здравствуйте, rg45, Вы писали:
R>·>Можно. Внезапно для этого и придумали пользовательские типы, инкапсуляцию и т.п. R>Внезапно, таким путём мы очень быстро придем к тому, что простые типы данных вообще нельзя использовать в чистом виде, а только через классы-обёртки.
А вы не приходите.
R>Да почему, собственно, только простые — любые! Хочешь использовать какой-то определенный пользователем класс, но не используешь все операции? Будь добр, напиши для него класс-обертку! Ты только так всегда делаешь?
Нет.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Да вы правы typedef избыточен, я просто скопировал из вопроса
Но в целом название ElementId и LogicalId с реализацие в виде вектора, например у меня вызывают некоторые вопросы.
Здравствуйте, kov_serg, Вы писали:
_>Но в целом название ElementId и LogicalId с реализацие в виде вектора, например у меня вызывают некоторые вопросы.
Ну так, тебе ни что не мешает задать эти вопросы автору.
--
Справедливость выше закона. А человечность выше справедливости.
Здравствуйте, rg45, Вы писали:
r> ·>Не надо так делать. Лучше так: r> Обоснование будет какое-нибудь?
Код проще читать и поддерживать.
r> ·> // методы, имеющие смысл для id, а не вся простыня вектора r> А почему ты уверен, что не вся простыня вектора имеет смысл для ID?
Потому что ID это (is-a) не вектор.
r> Если человек выбрал вектор для задания собственных типов, то, возможно, ему и нужна вся "простыня"?
Интуитивно уверен, что невозможно в данном случае. Буду рад услышать обоснование нужности, желательно от автора.
Здравствуйте, ·, Вы писали:
r>> Обоснование будет какое-нибудь? ·>Код проще читать и поддерживать.
Ты про какой код? Любой, или конткретный?
r>> А почему ты уверен, что не вся простыня вектора имеет смысл для ID? ·>Потому что ID это (is-a) не вектор.
Откуда ты знаешь, что у него за ID? Он мог бы заменить оригинальные имена на безликие Foo и Bar. К чему бы ты тогда придрался?
·>Интуитивно уверен, что невозможно в данном случае. Буду рад услышать обоснование нужности, желательно от автора.
Обоснования делает тот, кто делает утверждения. Так заведено.
--
Справедливость выше закона. А человечность выше справедливости.
Здравствуйте, rg45, Вы писали:
r>>> Обоснование будет какое-нибудь? R>·>Код проще читать и поддерживать. R>Ты про какой код? Любой, или конткретный?
Конкретный, конечно. Любой код можно писать любым способом.
r>>> А почему ты уверен, что не вся простыня вектора имеет смысл для ID? R>·>Потому что ID это (is-a) не вектор. R>Откуда ты знаешь, что у него за ID? Он мог бы
Тогда бы это бы был бы другой вопрос бы. И я бы отвечал бы по-другому бы.
R>·>Интуитивно уверен, что невозможно в данном случае. Буду рад услышать обоснование нужности, желательно от автора. R>Обоснования делает тот, кто делает утверждения.
Судя по именам, это какая то конкретная предметная область, а значит это бизнес сущности, публичный интерфейс которых задаётся бизнес-требованиями, а не Стандартной библиотекой.
R>Так заведено.
Ещё в форумах заведено рассказывать о решаемой задаче, а не спрашивать почему выбранное решение не работает.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, rg45, Вы писали:
R>·>Потому что ID это (is-a) не вектор. R>А если он напишет так: R>... R>У тебя тоже возникнут замечания?
Ок. А чем это принципиально отличается от моего?
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, ·, Вы писали:
R>>Ты про какой код? Любой, или конткретный? ·>Конкретный, конечно. Любой код можно писать любым способом.
Похоже, ты знаешь больше деталей. Ну, так расскажи тогда, почему именно в этом конкретном случае "так делать не надо".
R>>Откуда ты знаешь, что у него за ID? Он мог бы ·>Тогда бы это бы был бы другой вопрос бы. И я бы отвечал бы по-другому бы. ·>Судя по именам, это какая то конкретная предметная область, а значит это бизнес сущности, публичный интерфейс которых задаётся бизнес-требованиями, а не Стандартной библиотекой.
То есть, ты по одним только именам реконструировал полную семантику типов и требования к ним. Ну, круто. Все экстрасенсы мира завидуют.
R>>Так заведено. ·>Ещё в форумах заведено рассказывать о решаемой задаче, а не спрашивать почему выбранное решение не работает.
То есть, если какой-то новичок в форуме допускает какую-то погрешность, это сразу даёт тебе повод говорить что попало?
--
Справедливость выше закона. А человечность выше справедливости.
Здравствуйте, rg45, Вы писали:
r> ·>Конкретный, конечно. Любой код можно писать любым способом. r> Похоже, ты знаешь больше деталей. Ну, так расскажи тогда, почему именно в этом конкретном случае "так делать не надо".
Я рассказал выше.
r> То есть, ты по одним только именам реконструировал полную семантику типов и требования к ним. Ну, круто. Все экстрасенсы мира завидуют.
Не экстрасенс, а опыт. Буду рад ошибиться, чему-нибудь новому научусь.
Ещё раз. Читай внимательно. Наследование — это создание is-a отношения. Т.е. "хитровывернутый вектор" может наследовать вектор. А вот id вектором не является, по крайней мере в общепринятой терминологии. Если у него там какой-то особенный такой id, который ещё и вектор, то у него плохое именование сущностей.
r> То есть, если какой-то новичок в форуме допускает какую-то погрешность, это сразу даёт тебе повод говорить что попало?
Так я не говорил что попало.
Здравствуйте, rg45, Вы писали:
r> R>>У тебя тоже возникнут замечания? r> ·>Ок. А чем это принципиально отличается от моего? r> Так это к тебе вопрос. Видишь ли ты здесь принципиальные отличия от своего варианта и есть ли у тебя какие-либо замечания?
не вижу, замечаний нет.
Выше я видел только домыслы и голословное постулирование
·>Не экстрасенс, а опыт. Буду рад ошибиться, чему-нибудь новому научусь.
Уникальный опыт, нужно заметить. Об этом опыте кто-нибудь ещё знает, кроме тебя?
·>Ещё раз. Читай внимательно.
Давай договоримся сразу: ты не говоришь мне, что делать, а я не говорю, куда тебе идти. Хорошо?
·>Наследование — это создание is-a отношения. Т.е. "хитровывернутый вектор" может наследовать вектор.
наследование? Ни в стартовом сообщении, ни в твоём, где "не надо так делать", никакого наследования не было. Вы с Shmj не из одной команды случайно?
·>А вот id вектором не является,
А это откуда следует? Просто потому что тебе так захотелось?
·>по крайней мере в общепринятой терминологии.
А почему ты уверен, что общепринятая терминология применима в данном конкретном случае?
·>Если у него там какой-то особенный такой id, который ещё и вектор, то у него плохое именование сущностей.
О, "если"! Т.е. сначала даем "эксперные" оценки, а после этого начинаем строить предположения — если то, а если это. Ну, сразу видно — опыт
·>Так я не говорил что попало.
Хорошо, говорил, не обосновывая. Разница не велика, имхо.
--
Справедливость выше закона. А человечность выше справедливости.
Здравствуйте, kov_serg, Вы писали:
_>Но в целом название ElementId и LogicalId с реализацие в виде вектора, например у меня вызывают некоторые вопросы.
Это запросто могут быть координаты в многомерном пространстве.
И запросто может быть так, что количество измерений в этом пространстве определяется динамически и неизвестно на этапе компиляции, поэтому и std::vector, а не std::array.
Здравствуйте, so5team, Вы писали:
S>Это запросто могут быть координаты в многомерном пространстве.
Это уже не id а набор признаков
S>И запросто может быть так, что количество измерений в этом пространстве определяется динамически и неизвестно на этапе компиляции, поэтому и std::vector, а не std::array.
Дело не в этом. Id предполагает хотя бы сравнение этих самых id
Здравствуйте, so5team, Вы писали:
S>Здравствуйте, kov_serg, Вы писали:
_>>Но в целом название ElementId и LogicalId с реализацие в виде вектора, например у меня вызывают некоторые вопросы.
S>Это запросто могут быть координаты в многомерном пространстве. S>И запросто может быть так, что количество измерений в этом пространстве определяется динамически и неизвестно на этапе компиляции, поэтому и std::vector, а не std::array.
ElementId — это уникальный Id элемента иерархии.
LogicalId — тоже Id элемента той же иерархии, но без определенного слоя.
Здравствуйте, so5team, Вы писали:
S>В проекте, которому сейчас помогаю, как раз объекты однозначно идентифицируются координатами в N-мерном пространстве. И это именно что полный аналог Id, а не набор признаков.
Но у вас же, скорее всего, нет ситуации, когда в некотором N-мерном пространстве вместе существуют объекты с N-x и N+y размерностям?
Здравствуйте, DenProg, Вы писали:
DP>ElementId — это уникальный Id элемента иерархии. DP>LogicalId — тоже Id элемента той же иерархии, но без определенного слоя.
ID это число однозначно идентифицирующее что-либо.
А тут это путь к объекту в некоторой иерархии.
Здравствуйте, rg45, Вы писали:
R>Здравствуйте, kov_serg, Вы писали:
_>>ID это число однозначно идентифицирующее что-либо.
R>Почему только число? А строка может быть?
Потому что из простых соображений на практике достаточно int32 или int64 для распределённых систем guid(int128)
Здравствуйте, cserg, Вы писали:
C>Здравствуйте, so5team, Вы писали:
S>>В проекте, которому сейчас помогаю, как раз объекты однозначно идентифицируются координатами в N-мерном пространстве. И это именно что полный аналог Id, а не набор признаков. C>Но у вас же, скорее всего, нет ситуации, когда в некотором N-мерном пространстве вместе существуют объекты с N-x и N+y размерностям?
А при чем здесь это? Посыл же был в том, что вектор целых вряд ли может служить в качестве ID. Я привел пример ситуации, когда может.
Касательно предметной области из которой был взят пример, то да, в рамках одного и того же N-мерного пространства не может быть объектов, координаты которых содержат (N-x) или (N+y) значений. Но в самом приложении одновременно существует несколько пространств разных размерностей.
Здравствуйте, kov_serg, Вы писали:
_>Здравствуйте, DenProg, Вы писали:
DP>>ElementId — это уникальный Id элемента иерархии. DP>>LogicalId — тоже Id элемента той же иерархии, но без определенного слоя.
_>ID это число однозначно идентифицирующее что-либо. _>А тут это путь к объекту в некоторой иерархии.
_>std::dict<ID,Path> absolute_paths; _>std::dict<ID,Path> logical_paths; _>std::dict<ID,Path> some_other_paths; _>std::dict<ID,Metadata> some_metadata;
Проблема в названии? У меня это вектор. Слава богу язык этого не запрещает. Про std::dict наверно раньше не слышал.
Здравствуйте, ·, Вы писали:
·>Здравствуйте, rg45, Вы писали:
r>> ·>Не надо так делать. Лучше так: r>> Обоснование будет какое-нибудь? ·>Код проще читать и поддерживать.
r>> ·> // методы, имеющие смысл для id, а не вся простыня вектора r>> А почему ты уверен, что не вся простыня вектора имеет смысл для ID? ·>Потому что ID это (is-a) не вектор.
r>> Если человек выбрал вектор для задания собственных типов, то, возможно, ему и нужна вся "простыня"? ·>Интуитивно уверен, что невозможно в данном случае. Буду рад услышать обоснование нужности, желательно от автора.
Нужны все основные методы вектора. И переопределять их в новом классе смысла нет.
Здравствуйте, DenProg, Вы писали:
DP>Проблема в названии? У меня это вектор. Слава богу язык этого не запрещает. Про std::dict наверно раньше не слышал.
Не заморачивайся это опечатка должно было быть std::map. Я просто обычно его переименовываю в dict
Здравствуйте, Кодт, Вы писали:
К>Я бы предложил не морочить себе голову, а просто завернуть в структуру. К>Пусть даже с публичным полем, — чтобы минимально возиться с вопросами, что надо от вектора, а что не надо. Потом при случае отрефакторить, благо, все точки использования хорошо видны (поиском по имени поля либо кровавым рефакторингом — сделать приватным и смотреть, где компиляция сломалась).
К>
Здравствуйте, kov_serg, Вы писали:
R>>Так что, вопрос можно ли использовать вектор для задания ID, или нельзя — это вообще оффтоп в данном случае.
_>Прикалываетесь?
Даже не думал.
_>
_>typedef int ID;
_>struct ElementId { ID value; };
_>struct LogicalId { ID value; };
_>
Не понял, что ты хочешь этим сказать. Разверни свою мысль словами, если не трудно.
--
Справедливость выше закона. А человечность выше справедливости.
я воспринял как несогласие. Только не понял, как какому именно из двух высказываний это несогласие относится:
Главный вопрос этой темы можно было бы переформулировать для чисел;
Вопрос, можно ли использовать вектор для задания ID, является оффтопом для данной темы.
Пояснишь?
--
Справедливость выше закона. А человечность выше справедливости.
я воспринял как несогласие. Только не понял, как какому именно из двух высказываний это несогласие относится:
R> Главный вопрос этой темы можно было бы переформулировать для чисел;
можно R> Вопрос, можно ли использовать вектор для задания ID, является оффтопом для данной темы.
я просто высказал сомнения что вектор это не самый удачный выбор для типа идентификатора
R>Пояснишь?
Вы просто не в том контексте смотрите. Поэтому и возникли такие разночтения.
> ElementId — это уникальный Id элемента иерархии. > LogicalId — тоже Id элемента той же иерархии, но без определенного слоя.
ElementId — это путь к элементу
LogicalId — это локальный путь, отностиельно некоторого узла.
Здравствуйте, kov_serg, Вы писали:
R>>Пояснишь? _>Вы просто не в том контексте смотрите. Поэтому и возникли такие разночтения. _> . . .
Разночтения возникли из-за того, что ты неожиданно перескочил к тому, что мы обсуждали выше. Я считал, что тот вопрос мы уже закрыли, но если хочешь, можем продолжить обсуждение.
_>я просто высказал сомнения что вектор это не самый удачный выбор для типа идентификатора
_>> ID это число однозначно идентифицирующее что-либо.
R>> Почему только число? А строка может быть?
R>Вот с этого места давай и продолжим. Твой ход.
Я смотрю вы заядлый шахматист.
Да строка может быть. Но желательно фиксированной длинны. Например "1PRTTaJesdNovgne6Ehcdu1fpEdX7913CK"
R>Там после этого с твоей стороны была ещё одна фраза, но я её воспринял как шутку, беря во внимание смайлик в конце утверждения.
Здравствуйте, kov_serg, Вы писали:
_>Да строка может быть. Но желательно фиксированной длинны. Например "1PRTTaJesdNovgne6Ehcdu1fpEdX7913CK"
Было бы здорово, если бы ты обосновывал свои утверждения а не просто постулировал. Для кого желательно, почему желательно, насколько желательно и т.п. В противном случае ты сам лишаешь меня возможности принять твою точку зрения.
--
Справедливость выше закона. А человечность выше справедливости.
Здравствуйте, rg45, Вы писали:
R>Было бы здорово, если бы ты обосновывал свои утверждения а не просто постулировал. Для кого желательно, почему желательно и т.п.
Для быстродействия желательно фиксированный размер данных равный размеру регистра процессора или хотябы не сильно избыточный (не превосходящий L1 кэш)
Данные фиксированной длинны лучше размещаются в памяти и их проще кэшировать, читать, писать, сравнивать, чем данные непредсказуемой длинны. Для которых обычно используют hash функции, что бы уменьшить кол-во обращений непосредственно к телу. Вобщем сплошные дополнительные накладные расходы из ничего.
ps: промежуточные представления в виде строки, тоже никто не запрещает
Здравствуйте, kov_serg, Вы писали:
R>>Было бы здорово, если бы ты обосновывал свои утверждения а не просто постулировал. Для кого желательно, почему желательно и т.п. _>Для быстродействия желательно фиксированный размер данных равный размеру регистра процессора или хотябы не сильно избыточный (не превосходящий L1 кэш) _>Данные фиксированной длинны лучше размещаются в памяти и их проще кэшировать, читать, писать, сравнивать, чем данные непредсказуемой длинны. Для которых обычно используют hash функции, что бы уменьшить кол-во обращений непосредственно к телу. Вобщем сплошные дополнительные накладные расходы из ничего.
_>ps: промежуточные представления в виде строки, тоже никто не запрещает
А, то есть, желательно с точки зрения быстродействия. Ну, ОК. То есть, в тех местах, где быстродействие не критично, допустимо применять также и строки переменной длины, согласен?
Итого, в качестве идентификаторов можно использовать: числа, перечисления и классы. Таким образом, если вернуться к началу дискусси
Здравствуйте, rg45, Вы писали:
R>Хорошо. И как мы приходим к заключению, что тип std::vector<int> не может или не должен использоваться в качестве ID.
Я нигде не писал что он не может быть использован. Я писал что возникают вопросы.
Типа:
— а не избыточенли такой тип в качестве идентификатора
— если это путь к объкету в некотором дереве то и называть его логичнее не идентификатором а "положением" location или "путём" path
— если это набор характеристик, то allele, bag of properties или вектором признаков
Здравствуйте, kov_serg, Вы писали:
_>Я нигде не писал что он не может быть использован. Я писал что возникают вопросы.
Ну, как обычно: на третий день дискуссии настал момент уточнить предмет спора
_>Типа: _>- а не избыточенли такой тип в качестве идентификатора
Всё может быть. Это вопрос к автору.
_>- если это путь к объкету в некотором дереве то и называть его логичнее не идентификатором а "положением" location или "путём" path _>- если это набор характеристик, то allele, bag of properties или вектором признаков
Всё может быть. Чего ты до сих пор не задал эти вопросы автору?
--
Справедливость выше закона. А человечность выше справедливости.
я воспринял как несогласие. Только не понял, как какому именно из двух высказываний это несогласие относится:
R>> Главный вопрос этой темы можно было бы переформулировать для чисел; _>можно R>> Вопрос, можно ли использовать вектор для задания ID, является оффтопом для данной темы. _>я просто высказал сомнения что вектор это не самый удачный выбор для типа идентификатора
R>>Пояснишь? _>Вы просто не в том контексте смотрите. Поэтому и возникли такие разночтения.
>> ElementId — это уникальный Id элемента иерархии. >> LogicalId — тоже Id элемента той же иерархии, но без определенного слоя.
_>ElementId — это путь к элементу _>LogicalId — это локальный путь, отностиельно некоторого узла.
_>То есть это дерево (аналог файловая система)
_>[ElementId] _>root-->a-->b-->c-->element_1 _>root-->a-->b-->element_2 _>root-->d-->a-->element_3 _>root-->e-->a-->element_4
_>[LogicalId] a-->>element_3
_>И в качестве идентификаторов логично использовать числа 1,2,3,4
_>То есть назвать это не Id а Path: _>ElementPath _>LogicalPath
Путь в данном случае — это способ реализации идентификатора. Id реализовано на основе path.
Здравствуйте, DenProg, Вы писали:
DP> DP>>ElementId — это уникальный Id элемента иерархии. DP> DP>>LogicalId — тоже Id элемента той же иерархии, но без определенного слоя. DP> Проблема в названии?
Да, название странное. Это Path, Position, Coords, Address, Location, и т.п. Неясно причём тут ID. Чем является элемент в векторе тогда?
Здравствуйте, DenProg, Вы писали:
DP> Нет, заводить на это отдельный класс и наследовать все методы вектора нет смысла, ибо они будут просто вызываться с теми же сигнатурами.
Точно все? и erase, и emplace, etc? А сравнение LogicalId и ElementId?
В любом случае, это недостаточное условие для применения наследования. Наследование подразумевает, что оно будет прозрачно приводиться к базовому типу и всё что работает с вектором должно работать так же как и с твоим классом. https://en.wikipedia.org/wiki/Composition_over_inheritance
Здравствуйте, ·, Вы писали:
·>Точно все? и erase, и emplace, etc? А сравнение LogicalId и ElementId?
Ну, с тем же успехом можно доколупаться и до простого целочисленного ID: "А вы точно собираетесь использовать, инкремент, унарный минус, исключающее или и др?".
--
Справедливость выше закона. А человечность выше справедливости.
Здравствуйте, rg45, Вы писали:
R>·>Точно все? и erase, и emplace, etc? А сравнение LogicalId и ElementId? R>Ну, с тем же успехом можно доколупаться и до простого целочисленного ID: "А вы точно собираетесь использовать, инкремент, унарный минус, исключающее или и др?".
Можно. Внезапно для этого и придумали пользовательские типы, инкапсуляцию и т.п.
Сабж же, как раз и спрашивают как типы сделать различными.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, ·, Вы писали:
·>Можно. Внезапно для этого и придумали пользовательские типы, инкапсуляцию и т.п.
Внезапно, таким путём мы очень быстро придем к тому, что простые типы данных вообще нельзя использовать в чистом виде, а только через классы-обёртки.
Да почему, собственно, только простые — любые! Хочешь использовать какой-то определенный пользователем класс, но не используешь все операции? Будь добр, напиши для него класс-обертку! Ты только так всегда делаешь?
--
Справедливость выше закона. А человечность выше справедливости.
Здравствуйте, ·, Вы писали:
·>Здравствуйте, DenProg, Вы писали:
DP>> Нет, заводить на это отдельный класс и наследовать все методы вектора нет смысла, ибо они будут просто вызываться с теми же сигнатурами. ·>Точно все? и erase, и emplace, etc? А сравнение LogicalId и ElementId?
Да, все. Для индентификации элемента и перемещения по иерархии больше ничего не надо. Сравнения LogicalId и ElementId не существует, тут долго объяснять, не буду.
·>В любом случае, это недостаточное условие для применения наследования. Наследование подразумевает, что оно будет прозрачно приводиться к базовому типу и всё что работает с вектором должно работать так же как и с твоим классом. ·>https://en.wikipedia.org/wiki/Composition_over_inheritance
Ну так оно и сейчас прозрачно приводится и работает, без перегрузки методов, нет?
Здравствуйте, ·, Вы писали:
·>Здравствуйте, rg45, Вы писали:
R>>·>Точно все? и erase, и emplace, etc? А сравнение LogicalId и ElementId? R>>Ну, с тем же успехом можно доколупаться и до простого целочисленного ID: "А вы точно собираетесь использовать, инкремент, унарный минус, исключающее или и др?". ·>Можно. Внезапно для этого и придумали пользовательские типы, инкапсуляцию и т.п. ·>Сабж же, как раз и спрашивают как типы сделать различными.
Я как раз и использую C++ для скорости и меньшего объема ресурсов, здесь же предлагается перейти подобию джаваскрипта или ему подобного, причем там, где это не нужно. Типы уже сделали различными во втором посте.
Здравствуйте, rg45, Вы писали:
R>И кроме того, подумалось. Ведь главный вопрос этой темы можно было бы без труда переформулировать и для чисел: R>Так что, вопрос можно ли использовать вектор для задания ID, или нельзя — это вообще оффтоп в данном случае.
не совсем. Для целочисленных зачастую лучше enum class.
Здравствуйте, DenProg, Вы писали:
DP> ·>Точно все? и erase, и emplace, etc? А сравнение LogicalId и ElementId? DP> Да, все. Для индентификации элемента и перемещения по иерархии больше ничего не надо. Сравнения LogicalId и ElementId не существует, тут долго объяснять, не буду.
Если использовать наследование, например как "struct Id : std::vector<int> {}", то сравниваться будут, а не должны.
DP> ·>https://en.wikipedia.org/wiki/Composition_over_inheritance DP> Ну так оно и сейчас прозрачно приводится и работает, без перегрузки методов, нет?
Так не должно же.
Здравствуйте, DenProg, Вы писали:
DP>·>Сабж же, как раз и спрашивают как типы сделать различными. DP>Я как раз и использую C++ для скорости и меньшего объема ресурсов, здесь же предлагается перейти подобию джаваскрипта или ему подобного, причем там, где это не нужно. Типы уже сделали различными во втором посте.
Не понял. Какие варианты из тут предложенных отличаются по скорости или ресурсам?! Ты, видимо, полагаешь, что C++ подобно джаваскрипту каждую строчку выполняет?
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, ·, Вы писали:
·>Здравствуйте, DenProg, Вы писали:
DP>>·>Сабж же, как раз и спрашивают как типы сделать различными. DP>>Я как раз и использую C++ для скорости и меньшего объема ресурсов, здесь же предлагается перейти подобию джаваскрипта или ему подобного, причем там, где это не нужно. Типы уже сделали различными во втором посте. ·> Не понял. Какие варианты из тут предложенных отличаются по скорости или ресурсам?! Ты, видимо, полагаешь, что C++ подобно джаваскрипту каждую строчку выполняет?
"Не множте сущности без необходимости". Не надо обертывать-переобертывать там, где этого не надо.
Здравствуйте, ·, Вы писали:
·>Здравствуйте, DenProg, Вы писали:
DP>> ·>Точно все? и erase, и emplace, etc? А сравнение LogicalId и ElementId? DP>> Да, все. Для индентификации элемента и перемещения по иерархии больше ничего не надо. Сравнения LogicalId и ElementId не существует, тут долго объяснять, не буду. ·>Если использовать наследование, например как "struct Id : std::vector<int> {}", то сравниваться будут, а не должны.
DP>> ·>https://en.wikipedia.org/wiki/Composition_over_inheritance DP>> Ну так оно и сейчас прозрачно приводится и работает, без перегрузки методов, нет? ·>Так не должно же.
Честно говоря лень читать эту простыню на википедии. Не силен я в академических знаниях. Но зная проект думаю что проблем в этой части не возникнет.
Здравствуйте, ·, Вы писали:
·>Если использовать наследование, например как "struct Id : std::vector<int> {}", то сравниваться будут, а не должны.
Справедливое замечание. Но, опять же, масштаб трагедии здесь ровно такой же, как и при использовании целочисленных айдишников. А их использовали, используют и будут использовать.
Мне и самому вариант решения с наследованием не очень нравится. Я вообще не люблю наследование, стараюсь его избегать. Но даже в этом варианте решения возможно достичь приемлемой типовой безопасности, накидав в тело класса несколько дополнительных определений. А чтоб не делать это для каждого типа в отдельности, можно использовать шаблон:
#include <iostream>
#include <vector>
template <typename Category>
struct MultiDimensionalId : std::vector<int>
{
using vector::vector; // Открываем все конструкоры vector для использования в этом классеbool operator == (const MultiDimensionalId&) const = default;
auto operator <=> (const MultiDimensionalId&) const = default;
bool operator == (const auto&) const = delete;
auto operator <=> (const auto&) const = delete;
};
using ElementId = MultiDimensionalId<class ElementCategory>;
using LogicalId = MultiDimensionalId<class LogicalCategory>;
int main()
{
std::cout << (ElementId{1, 2, 3} == ElementId{1, 2, 3}) << std::endl;
std::cout << (ElementId{1, 20, 3} >= ElementId{1, 2, 3}) << std::endl;
std::cout << (ElementId{1, 2, 3} < ElementId{1, 20, 3}) << std::endl;
// std::cout << (ElementId{1, 2, 3} == LogicalId{1, 2, 3}) << std::endl; // error: use of deleted function
//std::cout << (ElementId{1, 2, 3} >= LogicalId{1, 2, 3}) << std::endl; // error: use of deleted function
}
Повторюсь, я не считаю это лучшим решением, и не говорю, что делать нужно только так. Как по мне, идиома строгих типов, в том или ином варианте исполнения, здесь была бы в самый раз.
--
Справедливость выше закона. А человечность выше справедливости.
Здравствуйте, ·, Вы писали:
·>Сабж же, как раз и спрашивают как типы сделать различными.
Так вот именно. И для того, чтобы сделать типы различными, совсем не обязательно урезать список доступных операций. И получившиеся различные типы вполне могут быть подтипами одного типа без нарушения принципа подстановки Лисков. Это полностью отдельная задача.
Я не говорю, что твое решение плохое. Просто аргументация у тебя ни в дугу. А поначалу и вовсе никакой аргументации не было. Вроде царский указ зачитал.
--
Справедливость выше закона. А человечность выше справедливости.