[c++]: Определение защищённой функции класса возвращающей указатель
ну что за привычка пошла - писать "не компилируется", но не писать текст ошибки
template <class T>
class CFoo
{
protected:
template <class U> struct SGoo
{
};
SGoo<T>* c_MyFunction;
public:
void qq
{
std::cout << this->c_MyFunction << std::endl;
}
};
template <class T>
CFoo<T>::SGoo<T>* CFoo<T>::c_MyFunction {return 0;}
int main
{
CFoo<int> qqq;
qqq.qq;
return 0;
}
все компилится - gcc 3.2.2
ЗЫ у тебя нет ";" после class SGoo{}
d:\documents and settings\хозяин\мои документы\visual studio projects\dynamic array\listarrayimplementation.h(11) : warning C4346: 'CListArray<T>::SFrame<T>' : dependent name is not a type
prefix with 'typename' to indicate a type
d:\documents and settings\хозяин\мои документы\visual studio projects\dynamic array\listarrayimplementation.h(11) : error C2143: syntax error : missing ';' before '*'
syntax error : missing ';' before '*'
А вообще судя по названию .h заголовка ты изобретаешь велосипед. Может лучше использовать стандартные классы для создания array of lists?
А вообще судя по названию .h заголовка ты изобретаешь велосипед. Может лучше использовать стандартные классы для создания array of lists?Не, это критично по скорости. vector медленен: 1 элемент массивы - 1 элемент списка.
Вектор медленный? Для какой задачи он медленный? Для частого удаления элементов из середины - медленный. Для доступа по индексу - самый быстрый.
Вектор медленный? Для какой задачи он медленный? Для частого удаления элементов из середины - медленный. Для доступа по индексу - самый быстрый.Какова трудоёмкость?
template <class TCObj> class CTemplClass
{
template <class TSObj> struct SInner
{
TSObj m_Obj;
SInner: m_Obj(5) {}
};
SInner<TCObj> m_sInner;
protected:
SInner<TCObj> * GetInner;
public:
TCObj GetTCObj;
};
template <class TCObj> TCObj CTemplClass<TCObj>::GetTCObj
{
return GetInner->m_Obj;
}
template <class TCObj> typename CTemplClass<TCObj>::SInner<TCObj>* CTemplClass<TCObj>::GetInner
{
return &m_sInner;
}
int main(int argc, _TCHAR* argv[])
{
CTemplClass<int> cIntClass;
std::cout << cIntClass.GetTCObj << std::endl;
return 0;
}
Какая трудоёмкость?.. Может, ты опишешь поставленную тебе задачу, а я скажу, какие лучше контейнеры использовать?
Какая трудоёмкость?.. Может, ты опишешь поставленную тебе задачу, а я скажу, какие лучше контейнеры использовать?Задача: быстро загонять в динамический массив содержимое по указателю (read (pBuffer, nBytes. Иметь доступ сравнимый по скорости к обычному
T array[N];
И вектор тебя не устраивает чем?..
А ну сужу по его push_back. Что-то оно мне не нравиться - типа списка получается.
Почитай документацию, что ли. Вектор - это далеко не "типа списка".
Нет, доступ в векторе не типа списка, а как раз сравним с обычным массивом. И ещё там явно не дискретный прирост, то есть наращивание не n*n.
Как загнать в vector<T> массив T array[1000], только не push_back - вызов функции в цикле меня явно не устраивает!
Не понимаем элементарных структур данных и алгоритмов, зато умеем городить шаблоны.
Должно быть что-то типа умножения размера на константу (типа 2 чтобы асимптотическая трудоёмкость вставки была O(1)
Ты как создаёшь массив T array[1000]? Вот вместо создания этого массива создавай и заполняй вектор.
Ты как создаёшь массив T array[1000]? Вот вместо создания этого массива создавай и заполняй вектор.Так не пойдёт, я получаю по сети куски не больше определённого размера, но обычно длины 1024. Их мне и нужно запихивать в массив. А окончательную длину я всегда точно знать не могу.
Ну и делай алгоритм: получаешь кусок, запихиваешь в вектор. Если тебе важно хранить именно динамические буфферы, кладёшь в вектор T*, в чём проблема-то? Зачем писать свой темплейт класс, который (я уверен) будет работать медленнее вектора?
Получаешь данные по сети, и не можешь позволить себе 1 вызов функции на каждые 1024 байта ? Так не бывает
Должно быть что-то типа умножения размера на константу (типа 2 чтобы асимптотическая трудоёмкость вставки была O(1)Асимптотическая трудоёмкость вставки в конец вектора в задаче вставки туда неограниченного числа
элементов -- O(n*n так как при realloc'е (а лучше ничего сделать нельзя, не налагая требований на операционку и существование только одного вектора в программе) вектор будет, в худшем случае,
копироваться во вновь отведённую память полностью.
Байда про амортизированное постоянное время "O(n)+" верна только для программ, которые не наращивают
вектор постоянно, а крутятся в районе некоторого значения size -- добавляют, удаляют, добавляют, удаляют и т.д. И то, желательно, предварительно зарезервировав под вектор место с запасом.
По-настоящему что-то лучшее O(n*n) для вставки в конец одновременно с чем-то не хуже O(1) при индексации обеспечивает вектор векторов. Через него, обычно реализован дек. (На самом деле для вставки в конец там тоже O(n*n но мультипликативная константа настолько мала, что в реальных программах вектор векторов ведёт себя в этом плане вполне прилично).
Речь шла о последовательной вставке N элементов в вектор. И это ну никак не квадрат.
Асимптотическая трудоёмкость вставки в конец вектора в задаче вставки туда неограниченного числаГы-гы. Ну давай вместе посчитаем. Пусть в пустой вектор последовательно в конец вставляется N элементов. Для краткости будем считать, что N = 2^n. И пусть размер вектора при реаллокации увеличивается вдвое.
элементов -- O(n*n так как при realloc'е (а лучше ничего сделать нельзя, не налагая требований на операционку и существование только одного вектора в программе) вектор будет, в худшем случае,
копироваться во вновь отведённую память полностью.
Байда про амортизированное постоянное время "O(n)+" верна только для программ, которые не наращивают
вектор постоянно, а крутятся в районе некоторого значения size -- добавляют, удаляют, добавляют, удаляют и т.д. И то, желательно, предварительно зарезервировав под вектор место с запасом.
Таким образом, потребуется n реаллокаций (или n-1 ? Да похуй, лень аккуратно разбирать). При реаллокации номер k нужно скопировать 2^k уже добавленных элементов в новую область памяти.
Получаем: общее число операций равно чему-то типа N + сумма{k=1,...,n}(2^k) *, что очевидно имеет порядок O(N). Значит, на один элемент асимптотическая трудоёмкость составляет O(1).
, программа планируется для работы в фоновом режиме. Нельзя, чтобы она жрала много ресурсов. И 1024 раза в цикле добавлять в вектор нельзя.
Сначала напиши работающую программу
Все-таки O(N*log_k(N - где k - во сколько раз увеличивается массив при реаллокации.
Сначала напиши работающую программуЯ не один пишу, а класс-таки написал и скорость приличная - проигрыш вектору при доступе к элементам порядка 15-25%, но это учитывая, что массив состоит из набора кадров и приходится переходить на другой кадр. Сейчас буду оптимизировать добавление, думаю, здесь выигрыш будет больше 25%...
При добавлении 100Мб такая картина:
Мой класс - 0 клоков
Вектор - 406 клоков.
Чота не пойму никак, как это получилось, поясни
да, похоже что гоню
Мой класс - 0 клоковЧто это за бред?
Вектор - 406 клоков
PS Блин, и где те времена, когда я переписывал все стандартные вещи наивно думая, что у меня они будут работать быстрее?..
И 1024 раза в цикле добавлять в вектор нельзя.Тебе не предлагали побайтно переносить данные в вектор. Тебе предлагали хранить буферы в векторе.
Тебе не предлагали побайтно переносить данные в вектор. Тебе предлагали хранить буферы в векторе.Попробовал, скорость доступа становится ниже раза в 2 и уступает моему классу. Добавление происходит примерно со скоростью моего класса.
P.S. Это вопрос с историей. Я всё равно написал бы этот класс, мне интересно.
P.P.S. 0 и 406 - неудивительно, vector всё реаллокейтит и реаллокейтит (интересно, каково ему перетаскивать 50Мб буфера а мой планомерно добавляет кадры к списку. Правда, при рандомном доступе мой безбожно проиграет, но ,по логике задачи, его и не будет.
Чисто для интереса, покажи свой класс что ли...
Куда?
Что куда? Класс что ли? Да куда угодно...
Речь шла о последовательной вставке N элементов в вектор. И это ну никак не квадрат.Дык, это я ночью писал
Конечно, все вхождения O(n*n) надо заменить на O(n а O(n)+ на O(1)+.
покажи, плз, код (с std::vector с которым ты сравнивал код со своим классом.
ClistArray размещение кадров+заполнение всех данных числами -- 531
ClistArray последовательный доступ -- 141
ClistArray случайный доступ (меняем 10000 uint) -- 17547
vector reserve+insert(NULL) -- 0
vector размещение "кадров" и заполнение данными -- 188
vector линейный последовательный доступ -- 141
vector случайный доступ (меняем 10000 uint) -- 31
Да, последовательная вставка в авторский темплейт класс не производилась. Но алгоритм там while (my_size < required_size) add_one_frame.
лол
я тут просто попутно обнаружил, что можно сделать такую вставку:
void setFrame(unsigned int size, const byte* frame)
{
vector_of_bytes.insert(vector_of_bytes.endframe,frame+size);
}
честно говоря, всю жизнь думал, что работать должно только с обычными итераторами.
Так бы без этого треда и не узнал бы =)
лолЭто к чему?
Тайминги пробовал смотреть?
Как нужно замерять время, чтобы твой класс оказался быстрее вектора ? Поделись методикой, я ее для отчетов буду использовать
,, при линейном доступе скорость одинаковая. Рандомный доступ для моей задачи в принципе не нужен.
У меня была такая методика:
(1) Мой массив и вектор объявлялись пустыми
(2) Затем они увеличивались в размерах до 100Мб блоками по 1Кб.
Мой заполнялся в 2 раза быстрее. Вы знали, какую методику применил ? К тому же мой класс будет работать равномерно, не будет жрать ресурсы при реаллокейтах.
ClistArray размещение кадров+заполнение всех данных числами -- 531
vector размещение "кадров" и заполнение данными -- 188
Вы знали, какую методику применил ?И не сомневался.
А если гипотетический push_front применить, то твой класс не в 2 раза порвет вектор, а, наверное, в 20. Просто не надо ругать стандартные классы, если не умеешь ими пользоваться.
Затем они увеличивались в размерах до 100Мб блоками по 1Кб.Конкретно в коде, который ты мне дал, твои кадры занимали 4кб, а вектор заполнялся интами в нереальном размере. Ты со своим объектом вёл работу как со списком буфферов по 4кб, а с вектором как с массивом интов через operator[] (тогда уж сразу бы брал int* и работал с ним). Я просто переделал вектор интов в вектор буферов (векторов). Кстати, я в STL всё-таки профан.
Кстати, у меня ещё прога падает на дебаге. Впрочем, она не падает на релизе.
Это всего лишь обозначает, что в release она просто портит память.
См. смайлик. Речь шла о его проге.
в смысле, делал так?
void setFrameByIterations(unsigned int size, const int* frame)
{
unsigned int old_size = array_of_frames.size;
unsigned int new_size = old_size + size;
array_of_frames.resize( new_size);
for(unsigned int index = old_size; index < new_size; index++)
array_of_frames[index] = frame[index - old_size];
}
Нет, я говорил о конструкции вида int * pInts = &myVector[0];
>Нет, я говорил о конструкции вида int * pInts = &myVector[0];
эгм. разве это корректно?
В смысле, потом по этому указателю ходить.
Как впрочем, и по итератору.
Нам разве гарантируют, что вектор хранит свои внутренние данные в виде последовательного (относительно порядка элементов) и непрерывного (относительно области памяти) массива?
Короче. Если бы разработчики вектора хотели дать такую возможность - они бы просто определили оператор приведения к соответствующему массиву.
Гарантируют.
Думаю, во всех нормальных реализациях STL это верно.
Гарантируется сложность доступа, но из нее ничего не следует. Например, можно хранить элементы в обратном порядке
Но даже если и так - решение все равно не попадает под предусмотренное использование данных вектора.
Поэтому лучше так не делать.
Говорят, что инфа по этому поводу есть в стандарте. И в самом деле, если бы это было не так, то в STL'е не было бы возможности создавать примитивные буферы.
И в самом деле, если бы это было не так, то в STL'е не было бы возможности создавать примитивные буферы.Что ты имеешь ввиду?
The elements of a vector are stored contiguously, meaning that if v is a vector<T, Allocator> where T is some type other than bool, then it obeys the identity &v[n] == &v[0] + n for all 0 <= n < v.size.Стандарт, п. 23.2.4.1
Дай, плз, ссылочку на стандарт или сам стандарт.
Оставить комментарий
Olenenok
Определение защищённой функции класса возвращающей указатель на структуру определённую в области protected:Объвление функции:
Определение функции:
Или
И никакой из вариантов не компилируется, никто не знает что делать?