← All posts tagged C++

Drino

А вот если у меня есть класс и его специализация. Надо и там и там написать итератор и константный итератор. Ничего умнее "написать внутри общего для них виртуального класса шаблонный виртуальный класс для итератора, а потом в каждом из них унаследовать этот класс отдельно, а после унаследовать от его потомка 2 класса — iterator и const_iterator, мне в голову не приходит. При таком решении я не вижу способа сделать сколько-нибудь обобщённый Begin и End. Это нормальное решение, или есть что-то менее напряжное (копипаст не менее напряжен, увы)?

Drino

Итак, конкурс "наверни говна^W костылей 2012" продолжается. Сегодня задумался над такой проблемой — есть у меня класс вида
class myClass {
<...>
myClass operator + (const myClass&);
<...>
};
от которого я наследую класс inhClass:
class inhClass : public myClass { <...> };
Проблема в том, что operator+ я inhClass'у переопределять не хочу, да и вообще inhClass это такой myClass только с ещё парой-другой методов. А operator+ применённый к двум inhClass'ам вовзращает мне myClass, у которого этой самой пары методов нет. Вызывать inhClass(myClass) — нехорошо, ибо конструктор повлечёт за собой копирование довольно толстых внутренних данных.
Пока что решение проблемы выглядит так:
template < class T > myClass {
<...>
T operator+ (const T&);
<...>
};

class inhClass : public myClass <inhClass> {<...>};
А this в методах myClass приводится к T* reinterpret_cast'ом, угу.

Drino

Нашёл два относительно красивых костыля для решения проблемы из #1773614. Думаю они вообще говоря боянисты, но на изобретение их в качестве велосипедов пришлось изрыть полгугла (видимо не то искал, но бесполезно) и потратить полдня.
Объясню, зачем мне хотелось получить всякие стандартные операторы — есть у меня функция вида
template < class A, class B, class Func >
void joinMap ( map < A, B >* result, const map < A, B >& other, Func join);
И этот joinMap, например, берёт и применяет join ко всем ((*result)[it->first], it->second). Возвращаясь к проблеме — на получение operator-= придётся забить, ибо невозможно. Поэтому пишется темплейтная функция T& SubEq < T > (T&, const T&) и подобные ей (естественно они пихаются в личный неймспейс для костылей). Дальнейшее решение проблемы зависит от любви пользователя к извращениям.
Вариант 1 — пилим шаблонную функцию, которая принимает какой-либо шаблонный класс и другую шаблонную функцию, и возвращает эту функцию с уже использованным шаблоном. Нечто вроде
template < class T >
T& () ( T&, const T&) getEqOperator(vector < T >, T& () ( T&, const T&) oper) { return oper; }
Конечно не помешают темплейтные тайпдефы, дабы всё это выглядело получше (а они сами по себе уже большой костыль, который реализуется через struct).
Минусы — надо напилить по функции на каждую сигнатуру. С другой стороны альтернатива мне кажется несколько более кривой.
Вариант 2 — уточняем тип параметра-функции для нашего абстрактного joinMap.
template < class A, class B >
void joinMap ( map < A, B >* result, const map < A, B >& other, B& (*join) (B&, const B&));
Работает, но ровно до тех пор, пока нам не вздумается послать в качестве join что-нибудь, не влияющее на суть, но отличное от шаблона. И к величайшему несчастью
template < class A, class B, class C >
void joinMap ( map < A, B >* result, const map < A, B >& other, C (*join) (B&, const B&));
ппочему-то мешает g++ нормально определить типы.

Drino

*пиздец *re-usable
Дорогие жуйковчане! Объясните мне, идиоту, как красиво на C++ написать код, который в случае, если переменная flag равна 1 создаёт объект некоторого шаблонного класса с именем a используя один шаблонный параметр (например double), а в случае, если flag равно 2 создаёт объект этого же шаблонного класса с таким же именем, но другим шаблонным параметром (например int). Причём так, чтобы ими потом можно было пользоваться после этого if'а.
Суть без кучи букаф:
Хочу какой-нибудь кусок кода, изящно выполняющий
bool unicode;
<получение unicode>
if (unicode==false)
basic_string<char> str;
else
basic_string<wchar> str;
<Предположим, что после if str не удаляется. Тогда тут какие-то операции с str>
без моря копипасты. Пока что самое изящное решение предложил @proton — запихнуть всё, что идёт после этого в main'е в конструктор шаблонного класса. Но с моей точки зрения это — костыль.

Drino

Здравствуй, жуйк! Подскажи — как и чем читать сырцы большого проекта? Есть makefile.am и много-много папок. Как с ними можно разобраться? Алсо мне хочется послушать какие-нибудь методы борьбы с апатией, усталостью, вялостью и нежеланием что-либо делать. Заранее спасибо тебе, жуйк!

Drino

Жуйк, а жуйк, а что можно придумать кроме
int *a, *b;
a = new int[length];
<...>
b=a;
a = new int[length+1];
for (unsigned i=0; i<length; i++) a[i]=b[i];
delete b;
Для создания сколько-нибудь динамического по длине массива из int'ов?