+50.7
- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
namespace inter {
template<typename X>
struct tplClass {
private:
X _priv;
public:
tplClass(const X _generator) {
this->_priv = _generator;
return;
}
tplClass(const tplClass<int>& _a) {
this->_priv = _a.get();
return;
}
const X get(void) const {
return this->_priv;
}
};
template<typename X>
const tplClass<X> operator+(const tplClass<X>& _lha, const tplClass<X>& _rha) {
return tplClass<X>(_lha.get()+_rha.get());
}
}
int main(int argc, char* args[], char* envs[]) {
tplClass<int> a(5);
tplClass<double> b(3.1);
tplClass<double> c = a + b;
return 0;
}
1. Всё упрощено до невозможности. Описано только то, что необходимо для узрения говнокода.
2. Несмотря на то, что решение существует в очень известной книжке, я напоролся на говнокод лично, пока программу писал. Искал несколько дней проблему... Ну да... Бывает...
3. Говнокод заключается в том, что данный код не компилируется.
P.S. Если видите, что где-то есть дыра, то говорите, возможно я опечатался (злобная администрация исправить не даст), возможно в данном коде плюг опущен, возможно дыра у меня в голове. Конструктивная критика приветствуется.
P.P.S. Если вы решили просто написать, что (C++ == "говно") is true , то, пожалуйста, прошу вас как людей порядочных и воспитанных, имеющих совесть и ум, пройдите мимо. Если у вас нит ни ума, ни совести, ни порядочности, то можете писать про "естественную говнистость" C++, милости прошу.
Запостил: interested,
30 Октября 2009
interested 30.10.2009 12:32 # 0
Понятно, что на самом деле всё происходит в моём пространстве имён...
guest 30.10.2009 12:44 # 0
Такие вещи же по ссылке возвращаются. [/quote]
interested 30.10.2009 12:49 # 0
benin 30.10.2009 13:23 # 0
guest 30.10.2009 13:32 # 0
interested 30.10.2009 15:23 # 0
Правильнее сказать, что я не сторонник подобных мер.
Benin пишет правильно, что многое зависит от ситуации. Например, если мне пришлось возвращать "тяжёлый тип".
Мне такое делать приходилось. Но после недолгого "перепроектирования" получилось добавить сущность, которая что-то в себя инкапсулировала и агрегировалась другими классами.
guest 30.10.2009 14:59 # 0
Если по делу, то это учебный недоговнокод.
interested 30.10.2009 15:54 # 0
Никогда раньше не сталкивался с такой особенностью неявного привидения типов.
guest 30.10.2009 15:04 # 0
ну да operator+ тут не сможет инстанциироваться из-за неоднозначности (мб int, мб double)
interested 30.10.2009 15:46 # 0
Компилятор вообще говорит, что не найден оператор сложения.
Если написать два честных, нешаблонных, сложения, то код скомпилируется и верно выполнится
g26g 30.10.2009 16:34 # 0
const tplClass<X> operator+(const tplClass<X>& _lha, const tplClass<Y>& _rha) {
return tplClass<X>(_lha.get()+_rha.get());
}
interested 30.10.2009 17:06 # 0
g26g 30.10.2009 17:37 # 0
естественно, зависит от первого параметра.
можешь специализировать шаблон, но вообще, это ахтунг - делать такие операторы.
interested 30.10.2009 17:56 # 0
Матрицы не складываются...
Если по-вашему писать (я пробовал), то выходит фиговрина =[
С тремя параметрами та, же фиговина... Но там я чувствовал, что есть двусмысленность...
И пошёл искать траблу...
Вот нашёл через некоторое время. Я сначала думал посмотрю в библиотеке стандартной, там же есть complex<typename _Tp>, да так и не разобрался, очень что-то замудрёно всё...
g26g 30.10.2009 18:10 # 0
думаю, лучше не парить мозг а написать шаблонный Add.
что-то вроде
template<typename R, typename X, typename Y>
const tplClass<R> Add(const tplClass<X> x, const tplClass<Y> y)
{
return tplClass<R>(x.get() + y.get());
}
interested 30.10.2009 18:18 # 0
Мне вот очень хотелось именно такую вычурню сделать =] Вот прям жёсткое желание себе в попу вставить, да поглубже =] И ведь нашёл у Скотта Мейерса как раз такую штуку! =]
guest 30.10.2009 16:52 # 0
interested 30.10.2009 17:10 # 0
Глядим.
Можно сварганить две функции: int int и double double ; По сути ни одна из них не может удовлетворить поставленной перед компилятором задачи. Он и не находит функцию. Вот в чём дело!
Однако, если функции будут не шаблонные, а ручками прописанные, то код сработает.
То есть, при выводе шаблона не работает кастинг типов!!!
guest 30.10.2009 17:16 # +1
interested 30.10.2009 17:38 # 0
Ан нифига...
guest 30.10.2009 17:48 # 0
c = a.Add<double>( b ); чтобы можно было явно указать тип параметра.
g26g 30.10.2009 18:07 # 0
guest 31.10.2009 23:54 # 0
Всегда Ваш, К.О.
guest 30.10.2009 17:44 # 0
interested 30.10.2009 18:08 # 0
Но в конструкторе здесь есть некорректность.
guest 30.10.2009 19:04 # 0
interested 30.10.2009 19:37 # 0
Если вам известны проблемы, то вы прямо и напишите: так вот и так, возникают неприятности. Я перестану писать его там...
guest 30.10.2009 21:24 # +1
interested 30.10.2009 21:41 # 0
Например я пытаюсь на очердной сетке, создать новый объект обсчёта, от этой сетки. Однако, метод обсчёта требует выполнения некоторых критериев устойчивости. Я проверяю эти критерии для переданной сетки значений начиная с самого простого. Если какой-то из критериев не выполняется, я логирую проблему и выхожу из конструктора. Создающая обсчёт программа или клиентский объект, увидев, что произошла ошибка удалит счётный объект и попытается прибегнуть к другой схеме или вовсе прекратит работу, сообщив, что всё уже вне пределов действия модели.
Простой пример, метод прогонки, который хочет, чтобы для переданной матрицы граничные прогоночные коэффициенты были бы меньше одного, а сумма побочных диагоналей меньше основной. Проверить начальные коэффициенты очень легко, дело трёх операций, а вот подсчёт суммы -- операция трудоёмкая. Если коэффициенты уже неверны, продолжать проверку и обсчёт нет смысла, нужно обращать матрицу приближённо, итерациями.
guest 31.10.2009 10:58 # 0
Тебе даже не придеться делать удаление обьекта, тк компилятор сделает это за тебя.
Если за тебя что-то делает компилятор, то ты уверен в этом, тк он точно ничего не забудет, в отличии от тебя. А на практике часто где-нибудь да забывают...
guest 31.10.2009 17:32 # +3
interested 31.10.2009 21:37 # 0
Генерация исключения в конструкторе может приводить к непредвиденному результату.
guest 01.11.2009 02:43 # 0
interested 01.11.2009 08:59 # 0
interested 30.10.2009 21:49 # 0
И такие вот у меня конструкторы встречаются someClass(unsigned int size):_array(valarray<double>(0.0,size)) { }
guest 31.10.2009 11:02 # 0
А вообще он просто не нужен в тех функциях, в которых ты не возращаешь параметры. Незнаю зачем писать несколько лишних букв.
interested 31.10.2009 21:45 # 0
Говнокод с return сейчас продемонстрирую.
guest 01.11.2009 02:45 # 0
guest 30.10.2009 21:06 # 0
Естественно несколько return'ов - это для пущей надёжности. Хоть один, да сработает. Поэтому он не краснея смотрит начальнику в лицо и говорит, что пишет самый надёжный код на планете.
guest 04.11.2009 16:51 # +1
1) есть неприятность с конструктором:
tplClass(const tplClass<int>& _a)
зачем привязка только к int?
2) в принципе, можно было бы сделать, чтобы int+double и double+int возвращали double, если бы был typeof. Скажем, так:
может быть в boost::mpl есть что-нибудь заместо typeof. Некоторые компиляторы предоставляют что-то подобное. Но, опять же, хотелось бы обходиться без обязательного наличия конструкторов по-умолчанию.
Можно попробовать, например, через boost::mpl описать правила привидения типов, в соответствии со стандартом. Например,
, но, наверное, это чересчур геморно :)
guest 04.11.2009 16:53 # 0
не надо делать имена с подчёркиванием в начале, ни одним, ни двумя, - они зарезервированы для компиляторов и писателей стандартных библиотек.
interested 04.11.2009 17:19 # 0
Мне приведение типов было нужно всё равно, для обращения и для других функций, думалось, что всё с шаблонным сложением сработает, а оно не захотело. Я запостил. =]
>зачем привязка только к int?
Этот неявный конструктор и есть неявное преобразование из tplClass<int> в любой другой. Предполагается, что их тут два tplClass<int> и tplClass<double>.
Предлагаете другой способ неявного привидения типов?
Вообще было бы правильным решением сделать код, который бы генерировал код для неявного преобразования шаблонных классов для используемых в программе конкретизаций, типы которых неявно приводимы. (и что было бы тогда с tplClass< tplClass<int> >? Как вычислить все типы к которым он приводится...)
>не надо делать имена с подчёркиванием в начале
Буду иметь в виду.
Я не пишу обычно подчёркиваний. яПишутВотТакВотССамогоДетства. Просто я код "передрал" и для однообразия всем добавил _ =] По-моему из STL для какого-то сложения был код, я его выдрал и перекроил, чтобы сюда поднять.
Я же сначала в STL и полез поискать решение проблемы, а не в книжки... Думаю, разберусь в коде, сделаю, как они. А там нету... =[