- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
//Я думал тоже так сделать, но иногда для параметра нужны дополнительные аргументы. Например есть operator()(float, int preciseness). С запятыми такого не сделаешь. Я это применил в своих массивах. Можно написать так:
Array<int> arr;
arr.Init(), 5, 7, 65, 99, 267; //Инициализирует массива числами, перечисленными через запятую
//Кстати, сделал такое добавление в массив:
arr.Insert(0), 5, 7, 3; //Добавляет числа вначало массива
arr.Insert($), 888, 25, 76; //Добавляет в конец
arr.Insert($/2), 65, 23; //В середину
//Знак доллара сделал для схожести с языком D. Теперь не надо писать arr.length, можно писать $. Вообще, это должно быть медленнее, но компилятор оптимизирует и по тестам получается так же.
//P. S. В govnokod.ru не заносить.
Кстати, как он это сделал? Через препроцессор вроде не выйдет.
xD
А дальше уж хD
> #define $ CurrentArray.length
Так это он что, перед каждой работой с массивом меняет этот глобальный указатель? Удобно, безопасно.
Клеветник.
>Удобно, безопасно.
Интересно, а можно сделать без этой дыры в безопасности? Ждём автора, пока отпишется.
Arr.Insert().($/2)
Чтобы метод Insert() менял глобальный указатель и указатель на функцию, делающую вставку в массив, а перегруженный оператор () уже вызывал это функцию по указателю для массива из глобального указателя.
В однопоточной программе работать будет. Только медленно и херово.
Для многопоточной не знаю, что придумать.
Ну ладно уже. Расскажу, как сделал.
Есть класс ContainerPosition, имеющий 2 переменных. Одна означает абсолютное смещение в массиве, вторая относительное. Здесь UINT_MAX - это конец массива, 0 -начало. Это по сути число с фиксированной точкой от 0 до 1. для класса определена операция деления, которая покомпонентно делит оба данных-члена на число. Статическая функция ContainerPosition::End() возвращает экземпляр класса с относительной позицией UINT_MAX и абсолютной 0. А $ определён так:
#define $ ContainerPosition::End()
Класс имеет функцию, позволяющую получить настоящую позицию в массиве. Функция Array::Insert принимает первым аргументом экземпляр ContainerPosition.
Всё, самое сложное описал, а как сделано преобразование int в ContainerPosition и сложение, думаю сами догадаетесь.
А ты на этом преобразовании скорость терять не будешь?
> Статическая функция ContainerPosition::End() возвращает экземпляр класса с относительной позицией UINT_MAX и абсолютной 0. А $ определён так:
#define $ ContainerPosition::End()
Нафига статические функции лепить, почему не написать просто
Почему был выбран именно vector?
Но есть один недостаток: если объекты полагаются на то, что их указатель this остаётся неизменным (например, хранит указатель на себя в отдельной переменной и на свои данные-члены), то будут проблемы. Хотя это может быть преимуществом - меньше возможностей наговнокодить.
Перемещай объекты не мовом, а специальным конструктором сдвига. В С++ надо будет для всех типов писать этот конструктор, а в С++0х это поддерживается на уровне языка, и для типов, для которых нету конструктора сдвига, вызовется побайтовый сдвиг.
http://www.gamedev.ru/projects/forum/?id=151691
Можно портировать на iPoh и послать в AppleStore.
Но выгляжу на 18, да?
Не нужно считать себя таким старым. Ваш духовный возраст лет на 13-16.
У вас уже понейронный сдвиг начался.
почитай внимательнее что такое move semantic ибо оно имеет крайне малое отношение с понятию move - "двигать" оно больше относится к "перемещать"
> вызовется побайтовый сдвиг.
разница между
A(A&&) и A(const A& ) есть только в том случае если A владеет указателями на внешние данные
тогда в move конструкторе их можно просто передать новому классу без копирования.
но допустим для Vector3D(Vector3D&&) и Vector3D(const Vector3D&) разницы не будет.
Vecotr3D - это POD, для него нет смысла писать конструктор сдвига.
Неа. Есть:
В этом случае придется делать лишнюю операцию копирования для возвращаемого значения, не зависимо от того, временный объект передали и его можно "портить" или нет. А тем более когда a+b+c+...+z+..., то бесполезных операций копирования становится слишком много.
При этом, если есть перегрузка конструктора для временных объектов, которые можно без последствий портить:
, то есть возможность не копировать каждый раз возвращаемый объект, а использовать возврат ссылки на уже существующий временный объект RValue, в котором можно без последствий разместить результат работы оператора.
Впрочем, 10% разницы при добавлении в конец — это, скорее всего, из-за особенности реализации STL в Visual Studio 2010.
обычно STL переписывают для того чтоб получить более простые вещи, ибо STL кишит избыточной универсальностью из-за которой страдает быстродействие.
очень часто вседозволенность порождает говнокод
может в случае потребности добавления в начало лучше подумать над каким нибудь более умным решением?
к стати твой вектор не гарантирует что индекс элемента останется тем же, так как при добавлении в начало уже новый элемент будет иметь индекс 0, и если кто-то сохранил индекс по которому он обращался к старому нулевому элементу, то его ждет эпичный фейл при повторном обращении.
>Нафига статические функции лепить, почему не написать просто
Потому что класс имеет закрытый конструктор, чтобы пользователь не догадался, что здесь отдельный класс. Пусть пользователь массива считает, что $ - это конец массива, который почему-то нельзя сохранить.
Хотя можно было сделать end статической переменной класса, не помню, почему я так не сделал. По-моему была какая-то причина. Надо перечитать код.
Мсье изобрёл std::deque?
верной дорогой идет товарищ!
ОЛОЛОНАБАШОРК
http://en.wikipedia.org/wiki/Double-ended_queue#Implementations
А почему - хз. Может, его достали говнокоды с ГД.ру.
Хорошо, занесем в личное дело.