LINUX.ORG.RU

С++ создать ограниченный тип


0

3

в Ада можно сделать собственный подтип:

subtype Data is Integer;
subtype Age is Data range 0..140;

как нибудь можно сделать подобное в c++?

★★★★★

Последнее исправление: splinter (всего исправлений: 1)

class MyStrictedInt, в конструкторе, операторе присваивания бросаешь исключение

vvviperrr ★★★★★
()
Последнее исправление: vvviperrr (всего исправлений: 1)

Наследование или агрегация.

KblCb ★★★★★
()

Подумал, что речь о limited-типах.

tailgunner ★★★★★
()

Если очень захотеть, можно в космос улететь.

Создаешь класс, переопределяешь ему все операторы, ставишь всюду проверку текущего значения. В итоге работать будет, но медленно. Потому что все проверки будут происходить только при выполнении кода, но не компилятором. Да и сопровождение такого кода - жесть.

Может, лучше просто писать на Ada?..

Deleted
()
Последнее исправление: Deleted (всего исправлений: 1)
Ответ на: комментарий от Deleted

в Ада можно сделать собственный подтип

Может, лучше просто писать на Ada?..

Еще с ТСа адовый тред про то, как и чего он на аде пишет, раз можно... А то плюсы да плюсы...

slackwarrior ★★★★★
()
Ответ на: комментарий от O02eg

А Ada на этапе компиляции выводит ограничения для результатов операций?

В некоторых случаях. Про это было в Ada Gems.

Deleted
()
Ответ на: комментарий от unsigned

Проверки можно запихнуть в compile-time (там, где возможно).

В случае C++ - слишком много ручной работы. Придется определять, где можно, где нельзя. А потом не дай Бог это еще и менять :)

Deleted
()
Ответ на: комментарий от Deleted

Создаешь класс, переопределяешь ему все операторы

А зачем все? Может, я чего-то не понимаю, но достаточно проверки в операторе присваивания.

tailgunner ★★★★★
()
Последнее исправление: tailgunner (всего исправлений: 1)

что будет на аде если написать (без понятия какой там синтаксис, но суть уловишь):

foo, bar, baz : Age
foo <- age_from_outterworld
bar <- age_from_outterworld
baz = foo + bar

если в foo=1 bar=140, что будет в baz, когда будут выполняться проверки?

qnikst ★★★★★
()

Пиши на аде, зачем тебе кресты? Ада - хороший, годный язык.

nanoolinux ★★★★
()
Ответ на: комментарий от qnikst

Тогда, очевидно, ты внутри плюса проверяешь выход за диапазон

anonymous
()
Ответ на: комментарий от bhfq

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

tff
()
Ответ на: комментарий от Deleted

Создаешь класс, переопределяешь ему все операторы, ставишь всюду проверку текущего значения. В итоге работать будет, но медленно.

также как и в аде.

Потому что все проверки будут происходить только при выполнении кода, но не компилятором

а зачем нужны проверки компилятором? Если ты можешь писать 10..20, а пишешь 100500, то тебе рассказать, кто тут идиот, ты, или компилятор? Проверки и нужны только в рантайме, где глупый пользователь вполне может ввести 100500 туда, где 10..20.

Да и сопровождение такого кода - жесть.

а когда такой код закопан внутрь интерпретатора, то это чем-то лучше?

emulek
()

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

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

next_time ★★★★★
()
Ответ на: комментарий от Deleted

но не компилятором

с какой стати? захочу, через макрос DEBUG сделаю и будут проверки компилятором, только зачем?

next_time ★★★★★
()
Ответ на: комментарий от tff

это стандартное обозначение в типизированном лямбда-исчислении

NEEEEEERD!

По сабжу. Я не понимаю, зачем это надо. Можно, конечно, создать класс и перегрузить арифметические операторы и оператор присваивания. Но я сходу не вижу применения. А для скрытия реализации придумали typedef.

DELIRIUM ☆☆☆☆☆
()
Последнее исправление: DELIRIUM (всего исправлений: 1)
Ответ на: комментарий от emulek

Если ты можешь писать 10..20, а пишешь 100500, то тебе рассказать, кто тут идиот

Допустим таким образом я хочу сбривать любые данные выше или меньше заданного типа.(к примеру данные с АЦП). К тому же для читаемости кода так выглядит намного лучше.

а зачем нужны проверки компилятором?

Это к тем кто затеял конкурс на унифицированный ЯП для НАТО.

splinter ★★★★★
() автор топика
Ответ на: комментарий от next_time

нет, мне реально надо ограничить тип. К примеру мне нужен тип 0 - 360 int, для измерения градусов.

splinter ★★★★★
() автор топика
Ответ на: комментарий от next_time

Ну так она и лучше - во-первых, в ней это ограничение уже есть; во-вторых, компилятор сам решает, когда делать статическую проверку, а когда динамическую - в Си++ это просто невозможно.

tailgunner ★★★★★
()
Ответ на: комментарий от splinter

Допустим таким образом я хочу сбривать любые данные выше или меньше заданного типа.(к примеру данные с АЦП).

не понял. В чём проблема-то?

К тому же для читаемости кода так выглядит намного лучше.

тем, что в какой-то заднице закопано, что больше 1742х нельзя? А я потому должен тонны сырцов перекопать, на тему, где и когда и зачем, какой-то дебил запретил >1742? Ага, очень читаемо. Или переменные у тебя называются this_variable_less1742_or_equ да?

Это к тем кто затеял конкурс на унифицированный ЯП для НАТО.

а ты к чему это всё писал?

emulek
()
Ответ на: комментарий от splinter

нет, мне реально надо ограничить тип. К примеру мне нужен тип 0 - 360 int, для измерения градусов.

вообще-то, IRL 400 градусов, это один оборот и ещё бутылка 40 градусов. Твой тип про это в курсе?

emulek
()
Ответ на: комментарий от emulek

ну я понимаю что для тебя евклидова геометрия и законы Ньютона это абсурд для средней школы.

splinter ★★★★★
() автор топика
Ответ на: комментарий от splinter

Что будет с твоими градусами когда ты сложишь 270 с 210? Какое поведение ты ожидаешь? Модуль от суммы по 360?

В общем случае очевидно что нужен новый тип данных. Если тебе часто нужны такие штукенции вроде A..B, где A и B типа int, то я бы на твоём месте написал шиблонный класс вроде

template <int From, int To>
class Distance {
...
};

В котором реализовать нужное тебе поведение(перегрузить операторы, указать нужные асёрты или еще что). Потом просто делаешь

typedef Distance<0, 360> Degree;
и получаешь градусы, которые работают как тебе надо.

tff
()
Ответ на: комментарий от splinter

ну я понимаю что для тебя евклидова геометрия и законы Ньютона это абсурд для средней школы.

нет. Не абсурд. Но вот IRL, если что-то повернуть больше, чем на 360 градусов, то никаких исключений IRL не происходит. УМВР. Крутится дальше. А вот у тебя — какой-то странный градус. Упёртый в один оборот. А что дальше? Сингулярность?

emulek
()
Ответ на: комментарий от next_time

компилятор сам решает, когда делать статическую проверку, а когда динамическую - в Си++ это просто невозможно.

неправда, в С++ это очень даже возможно

Покажи, как.

tailgunner ★★★★★
()
Ответ на: комментарий от tff

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

next_time ★★★★★
()
Ответ на: комментарий от next_time

неправда, в С++ это очень даже возможно — элементарно организуется на уровне классов

правда, но, если одно из предложений в С++14 примут, то станет неправдой

wota ★★
()
Ответ на: комментарий от splinter

да собственно никаких.

да собственно есть. Вот написали мы код, который с АЦП жрёт максимум 9.9999 попугаев. А он взял, и ВНЕЗАПНО дал 10. Мой код этого даже не заметит, а твой — рухнет. Ибо твой тип 10 не умеет. Проблема. У тебя.

emulek
()
Ответ на: комментарий от emulek

Вот написали мы код, который с АЦП жрёт максимум 9.9999 попугаев. А он взял, и ВНЕЗАПНО дал 10. Мой код этого даже не заметит, а твой — рухнет. Ибо твой тип 10 не умеет. Проблема. У тебя.

Доктор, ты дебил.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

А вот так:


const  int var = 1;

int main() {
   if(!var) cout<<"c";
    return 0;
}

Disasm:

0x400624	push   rbp
0x400625	mov    rbp,rsp
0x400628	mov    eax,0x0
0x40062d	pop    rbp
0x40062e	re

const  int var = 1;

int main() {
   if(var) cout<<"c";
    return 0;
}

Disasm:

0x4006d4	push   rbp
0x4006d5	mov    rbp,rsp
0x4006d8	mov    esi,0x40083e
0x4006dd	mov    edi,0x601040
0x4006e2	call   0x4005e0 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@plt>
0x4006e7	mov    eax,0x0
0x4006ec	pop    rbp
0x4006ed	ret

Такие дела.

next_time ★★★★★
()
Ответ на: комментарий от tailgunner

Вот написали мы код, который с АЦП жрёт максимум 9.9999 попугаев. А он взял, и ВНЕЗАПНО дал 10. Мой код этого даже не заметит, а твой — рухнет. Ибо твой тип 10 не умеет. Проблема. У тебя.

Доктор, ты дебил.

ну не идиот жеж. Объясни, может пойму.

emulek
()
Ответ на: комментарий от tailgunner

Конечно, в Аде решение точно на таком же уровне)

next_time ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.