• ↓
  • ↑
  • ⇑
 
Записи с темой: программизм (список заголовков)
10:22 

STL, STL, повернись ко мне передом, а к автору - чем получится...

Йа волосат и бородат!

Решил я написать от нечего делать фигню со свистелками и перделками списками и внезапно наткнулся вот на такую радость:


list::rbegin() // Returns an iterator addressing the first element in a reversed list.
list::end() // Returns an iterator that addresses the location succeeding the last element in a list. If the list is empty, then list::end == list::begin.
(c) MSDN

reverse_iterator rbegin()
{ // return iterator for beginning of reversed mutable sequence
return (reverse_iterator(end()));
}
(c) <list>

Остается молиться, что оный rbegin() не используется где-нибудь в шаблонах <algorythm>...


PS: found on MS Visual Studio 2005.


UPD: Порылся в исходниках STL и обнаружил вот такую прелесть:


_RanIt __CLR_OR_THIS_CALL base() const
{ // return wrapped iterator
return (current);
}
reference __CLR_OR_THIS_CALL operator*() const
{ // return designated value
_RanIt _Tmp = current;
return (*--_Tmp);
}
pointer __CLR_OR_THIS_CALL operator->() const
{ // return pointer to class object
return (&**this);
}

То есть, обратный итератор возвращает изображает, будто бы он ссылается на правильный элемент, но при попытке получить обычный итератор вернет не его, а... внезапно итератор, ссылающийся на следующий элемент. Просто прекрасно! :)




@темы: программизм

08:21 

Есть у кого идеи?

Йа волосат и бородат!

Вот есть у меня класс. Даже два — Класс1 и Класс2. И оба используются в качестве параметров шаблона в ШаблонноКлассе. Вот же теперь вопрос — как можно сообщить Классу1 о Классе2, использующимся в конкретном ШаблонноКлассе?


Пример:

class Param_1;
class Param_2;

class Param_1 {
public:
static void foo() { /*вызов Template_class::Par2::goo()*/ }
};
class Param_2 {
public:
static void goo() { /* ... */ }
};

template <typename Par1, typename Par2>
class Template_class {
void boo() { Par1::foo(); }
};


Весь вечер ломал голову. Так и не придумал.




[UPD]: Вот только я написал этот пост, как пришла в голову мысль:

using namespace std;

class Param_1
{
public:
template <typename C>
static void foo() { typename C::Par2::boo(); }
static void boo() { cout << "Param_1::boo()" << endl; }
};

class Param_2
{
public:
template <typename C>
static void foo() { typename C::Par1::boo(); }
static void boo() { cout << "Param_2::boo()" << endl; }
};

template <typename P1, typename P2>
class templated_class
{
public:
typedef P1 Par1;
typedef P2 Par2;
void foo() {
Par1::foo<templated_class<Par1, Par2> >();
Par2::foo<templated_class<Par1, Par2> >();
}
};

/* in main(): */
templated_class<Param_1, Param_2> c;
c.foo();
getch();




@темы: программизм

14:04 

Дебаговская тулза.

Йа волосат и бородат!

Обнаружил хорошую функцию WalkStack64 в Platform SDK, принадлежит DbgHelp.dll. Буду дома осваивать.




@темы: программизм

09:22 

Отказались от POSIX и устроили всем жопу

Йа волосат и бородат!

Узнал тут почему в реализации H323plus под Windows так много потоков. Оказывается в этом богомерзском выродке мысли человеческой aka MS Windows чем больше потоков и кольцевых буферов — тем плавнее отрабатывают эвенты. Поначалу это вызвало у меня недоумение, но потом, после обьяснений Вадима все оказалось очень просто.


Представим, что есть 2 реализации решения некоторой задачи — одна работает в одном потоке с непрерывной обработкой данных, другая — разделена на 2 потока с кольцевым буфером между ними, причем оба потока обрабатывают данные последовательно. В условиях когда для решения задачи число необходимых операций большое, т.е. задача достаточно ресурсоёмкая, вторая реализация будет работать плавнее, как бы странным это ни казалось. А все потому, что в Винде Проклятой используется вытесняющая многозадачность, означающее, что когда Винде вот прям щас понадобилось обработать эвент - активный поток может быть спокойно задвинут... В первом случае это будет означать паузу в работе, а вот второй, разделенный на два потока вариант, возможно, еще порыпается. Поэтому в H323plus так много потоков — ибо там нужна непрерывная обработка данных.


ЗЫ: Для тех, кто будет возникать по поводу незначительности перерыва, пример задачи - декодирование и воспроизведение звука.




@темы: программизм

18:16 

На будущее

Йа волосат и бородат!

Надо будет покопаться еще с Clutter toolkit и поиграться с On-line компилятором C++.




@темы: Программизм

15:48 

Списки и прочая мутотень

Йа волосат и бородат!

Вообще, STL, конечно, хорош. Полезен и вкусен. Но в задаче о синхронизации 2 потоков, когда защищаемый ресурс — цепочка буферов (которые добавляются в одном потоке и читаются в другом), а хотя бы один поток имеет большой приоритет, следует отказаться от STL и написать свой простенький список, пока ваша жизнь в дебаге не превратилась в один сплошной кошмар. Ибо долго в силу кучи операций. Да и не нужна вам отладочная информация самого STL, вы ж не его отлаживаете в этой задаче. К тому же код в STL не очень и прост для восприятия.




@темы: Программизм

15:24 

Я знаю, костанты неконстантны...

Йа волосат и бородат!

Вот простенький пример:


typedef /*some type here*/ T;
T const const_value = T(); // ok...
T const & const_ref = const_value; // ok...
T & volatile_ref = (T &;)const_ref; // ok?!..
volatile_ref = /*some value of T*/; // ok?!! Why?! =O.o=


Обьясните мне, господа хорошие, почему при изменении значения volatile_ref у меня замечательно меняется и значение const_value? Что, const теперь у нас стал нежестким ограничителем, да? Я вот не понимаю, почему средствами языка не производится контроль за изменяемыми по ссылке данными?


А вообще, я считаю такой код семантической ошибкой.



UPD: Компилятор - штатный от Microsoft Visual Studio 2005.




@темы: Программизм

void main()

главная