Форум программистов, компьютерный форум CyberForum.ru

Как быть и что делать? Трабла с шаблонами - C++

Восстановить пароль Регистрация
 
AnyOne697
 Аватар для AnyOne697
134 / 106 / 5
Регистрация: 22.05.2010
Сообщений: 532
28.06.2012, 03:53     Как быть и что делать? Трабла с шаблонами #1
Литературы по шаблонному программированию в Си++ так много, что поднимать и искать то, что нужно мне довольно долго...

Началось всё с того, что захотелось вывести в поток std::vector. Ну, сначала цикл, потом отнаследовал-перегрузил вывод. Потом ещё, ещё... А теперь. Не знаю зачем, но сделал фабрику вывода! Да, "ОМГ!".

Ну, собственно, вот и она. Трабл вот в чём - в силу не знания шаблонного программирования не могу знать, что править, чтобы работало. И няшно выглядело =)

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
template <class T>
class show{
    T m_el;
public:
    show<T>(T);
    friend ostream& operator << <>(ostream&, show&);
};
 
template <class T>
show::show(T el){ m_el = el; }
 
template <class T>
ostream& operator << (ostream& os, show& s){
    os << "{";
    for(int i = 0; i < s.m_el.size(); i++)
        os << s.m_el[i] << (i+1 != s.m_el.size()) ? "; " : "}";
 
    return os;
}
Использовать предполагаю как-то так:
C++
1
std::cout << show<vector<int>> s(v);
, где v - экземпляр класса вектора.
Сейчас цикл на инте, потом сделаю на итераторе. Чтобы для всего STL =)

Заранее спасибо.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
igorrr37
 Аватар для igorrr37
1593 / 1221 / 118
Регистрация: 21.12.2010
Сообщений: 1,868
Записей в блоге: 7
28.06.2012, 16:10     Как быть и что делать? Трабла с шаблонами #2
Хм, а почему по значению а не по ссылке
C++
1
2
3
4
5
6
7
8
9
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
36
37
#include <iostream>
#include <vector>
 
template <class T>
class Printer
{
public:
    Printer(T const&);
    friend std::ostream& operator << (std::ostream& os, Printer const& p)
    {
        for(auto const& val : p.rCon)
        {
            os << val << ' ';
        }
        return os;
    }
private:
    T const& rCon;
    Printer& operator=(const Printer&);
};
 
template <class T>
Printer<T>::Printer(T const& con) : rCon(con){}
 
int main()
{
    std::vector<int> v{1}, v1{1,2,3};
    {
        Printer<std::vector<int>> p(v);
        Printer<std::vector<int>> p1 = p;
        v.emplace_back(100);
        std::cout << p1 << std::endl;
    }
    v.emplace_back(200);
    std::cout << v.at(2);
    return 0;
}
AnyOne697
 Аватар для AnyOne697
134 / 106 / 5
Регистрация: 22.05.2010
Сообщений: 532
28.06.2012, 16:37  [ТС]     Как быть и что делать? Трабла с шаблонами #3
11ая строчка - это какой-то новый синтаксис из C++11? Мне казалось, что там ещё только черновики...

Впрочем, вот http://codepad.org/ZSYXkhd3
Синтаксиса я не знаю, поэтому исправить не могу...
igorrr37
 Аватар для igorrr37
1593 / 1221 / 118
Регистрация: 21.12.2010
Сообщений: 1,868
Записей в блоге: 7
28.06.2012, 16:58     Как быть и что делать? Трабла с шаблонами #4
можно так написать
C++
1
2
3
4
5
6
7
8
9
friend std::ostream& operator << (std::ostream& os, Printer const& p)
    {
        typename T::const_iterator it = p.rCon.begin(), itEnd = p.rCon.end();
        for(; it != itEnd; ++it)
        {
            std::cout << *it << ' ';
        }
        return os;
    }
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
28.06.2012, 17:08     Как быть и что делать? Трабла с шаблонами #5
AnyOne697, Там далеко не черновики. Осваивайте новый стандарт, совет вам.
emplace_back кстати тоже добавлено только в С++11
AnyOne697
 Аватар для AnyOne697
134 / 106 / 5
Регистрация: 22.05.2010
Сообщений: 532
28.06.2012, 17:17  [ТС]     Как быть и что делать? Трабла с шаблонами #6
А по поводу принта - какой-то он странный, стоит заметить... Шаманский. Код шамана. Мне до него далеко. Впрочем, работает - значит получиться скопипастить. Спасибо.

Добавлено через 1 минуту
И вот ещё что, кто нибудь даст ссылку на пояснение 11ой строчки?
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
28.06.2012, 17:35     Как быть и что делать? Трабла с шаблонами #7
AnyOne697, В чем же синтаксис не красивый? Намного более удобно чем было раньше.
Лямбды, range-based for, std::function/std::bind, std::random и прочие-прочие плюшки.

В плане пояснение? Тупо проход по контейнеру, используя новую версию цикла for...

Добавлено через 11 минут
Еще такой вариант предложу

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <iostream>
#include <iterator>
#include <vector>
 
template<typename T>
struct Printer
{
public:
   Printer(const T& col):collection(col)
   {
   }
private:
   T collection;
   template<typename T2>
   friend std::ostream& operator << (std::ostream&, const Printer<T2>&);
};
 
template<typename T>
std::ostream& operator <<(std::ostream& os, const Printer<T>& object)
{
   std::copy(object.collection.begin(), object.collection.end(), 
   std::ostream_iterator<typename T::value_type>(os, "\n"));
   return os;
}
 
int main()
{
   std::vector<int> v = {1,2,3,4,5};
   std::cout << Printer<std::vector<int>>(v) << std::endl;
}
http://liveworkspace.org/code/e9e705...a8e5fe4fb16370
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
28.06.2012, 20:14     Как быть и что делать? Трабла с шаблонами #8
Цитата Сообщение от ForEveR Посмотреть сообщение
std::vector<int> v = {1,2,3,4,5};
Компилятор эту строчку не пропускает.
AnyOne697
 Аватар для AnyOne697
134 / 106 / 5
Регистрация: 22.05.2010
Сообщений: 532
28.06.2012, 20:25  [ТС]     Как быть и что делать? Трабла с шаблонами #9
Цитата Сообщение от alsav22 Посмотреть сообщение
Компилятор эту строчку не пропускает.
С++11 это, не забываем.

Цитата Сообщение от ForEveR Посмотреть сообщение
C++
1
2
std::copy(object.collection.begin(), object.collection.end(), 
* *std::ostream_iterator<typename T::value_type>(os, "\n"));
Поясните работу. Уж больно мне понравилось. Хотя здесь и нельзя красиво обрамлять в фигурные скобки (без лишнего пробела), всё же интересно, почему это работает.
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
28.06.2012, 20:34     Как быть и что делать? Трабла с шаблонами #10
Цитата Сообщение от AnyOne697 Посмотреть сообщение
С++11 это, не забываем.
Чем это компилировать?
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
28.06.2012, 20:57     Как быть и что делать? Трабла с шаблонами #11
AnyOne697, Всегда у С++ было применение именно прикладное, именно поэтому шаблоны, метапрограммирование и прочее интересное.
Лямбда зачем? Ну очевидно же, чтобы не писать функтор на каждый чих.
Ну если живешь без этого всего - никогда не запрещает использовать (std::random это тот же boost::random - т.е. различные распределения и т.д.).
А вот насчет как работает - легко.
C++
1
ostream_iterator<typename T::value_type>(os, "\n")
создает итератор вывода типа T::value_type на поток os.
Если у T::value_type перегружен оператор вывода в поток - все будет окей. Используется это с алгоритмом copy (алгоритм copy копирует данные из последовательности [first-last) в последовательность, начало которой указывается в третьем параметре).
AnyOne697
 Аватар для AnyOne697
134 / 106 / 5
Регистрация: 22.05.2010
Сообщений: 532
28.06.2012, 21:38  [ТС]     Как быть и что делать? Трабла с шаблонами #12
Цитата Сообщение от ForEveR Посмотреть сообщение
никогда не запрещает использовать
В этом-то и проблема. Проблемы-то я описал: худший коллаборашн, жирный компилятор, больше требуется знать, слишком приторный сахар, порождающий как похожие, так и свои проблемы. Всё это давно расписано и раскритиковано точно так же, как и обрело своих поклонников. И когда нам дают выбор "как делать", это создаёт проблемы и решения то же спорны. Стоит только посмотреть Google C++ Style Guide, сколько там всего вырезано, чтобы понять, что порой некоторые вещи просто не нужны. Уже есть python, Java, Haskell - каждый для своей задачи. У Си++ есть дар, оно же и проклятие - почти полная совместимость супер-системным императивным детерминированным и ОЧЕНЬ БЫСТРЫМ Си, это и нужно использовать. Проектирование быстрых и стабильных систем огромными командами физиков, программистов, математиков и других специалистов области. И сахар, супер возможности здесь никак не способствуют. ИМХО, прошли времена когда на Си++ быстро делали быстрые приложения. Чтобы ни говорили, на Python'е всё равно с программируют быстрее, а десятикратное замедление будет незаметно на Core i7, тем более Python поддерживает параллелизм из коробки. На Java'е очень сложно выстрелить себе в ногу, что можно было и в Си, и в Си++, и в Си++11 тоже можно - никто не заменил указатели, лишь добавили, поэтому это язык останется языком обезьянок, которые кодят на пол ставки, пока опыта не наберутся. Haskell - вот это выбор настоящих amigo, которые плюют на мейнстрим и пишут своё. Не то что параллелизм из коробки, а математический параллелизм из коробки, встроенный в определение позволит использовать все 448 CUDA ядер у GTX560Ti448, оправдывая каждый цент этой довольно дешёвый (для enterprise) видеоадаптер.

Возможно, пригодятся лямбды, но они не ускорят производство в n-раз. Возможно у std::random лучше распределение, но производительность точно упала. Для enterprise решений лучше подключить специальную плату, который Linux поддерживает через /dev/random. А с std::random не факт что всё будет и сразу. Всё слишком запущено и Си++11 не панацея.

Добавлено через 1 минуту
Цитата Сообщение от ForEveR Посмотреть сообщение
создает итератор вывода типа T::value_type на поток os.
Если у T::value_type перегружен оператор вывода в поток - все будет окей. Используется это с алгоритмом copy (алгоритм copy копирует данные из последовательности [first-last) в последовательность, начало которой указывается в третьем параметре).
Спасибки. Не знаю правда, зачем это надо. Вроде бы производительность повыситься, но что происходит при создании
C++
1
ostream_iterator<typename T::value_type>(os, "\n")
я не знаю. Возможно быстрее будет просто вывести в поток. Быстрее и более гибко.
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
28.06.2012, 22:14     Как быть и что делать? Трабла с шаблонами #13
AnyOne697, Ну... У нас на работе вся логика написана на С++, то есть все ядро системы. Веб на питоне, с биндингом логики из плюсов. Плюсы такой же язык высокого уровня, как и остальные, достаточно выразителен и удобен, если его ЗНАТЬ.

По поводу вывода в поток, быстрее очевидно просто вывести в поток, но такой вывод во-первых использует стандартный алгоритм + выглядит эстетичнее)
AnyOne697
 Аватар для AnyOne697
134 / 106 / 5
Регистрация: 22.05.2010
Сообщений: 532
28.06.2012, 23:03  [ТС]     Как быть и что делать? Трабла с шаблонами #14
Цитата Сообщение от ForEveR Посмотреть сообщение
но такой вывод во-первых использует стандартный алгоритм + выглядит эстетичнее)
От первого я не понял профит, а со вторым не спорю. Выглядит ня)

Цитата Сообщение от ForEveR Посмотреть сообщение
У нас на работе вся логика написана на С++, то есть все ядро системы. Веб на питоне, с биндингом логики из плюсов. Плюсы такой же язык высокого уровня, как и остальные, достаточно выразителен и удобен, если его ЗНАТЬ.
И много у Вас на работе написано на Си++11? Мне кажется, логика написана задолго до появления первого черновика. Плюсы ни в коем случае не такой же язык высокого уровня. Это уродец от матери Си - языка средне-низкого уровня (ассемблерные вставки) и отца ООП - парадигмы, подразумевающая переход на высокий уровень программирования. Из-за этого у новичков в Си++ возникают проблемы, особенно когда они изучали смесь Си/Си++, который часто практикуется в ВУЗах из-за недостатка академических часов. И начинают прямо в классах вставлять ассемблерные вставки, где можно - где нельзя или не надо, появляются утечки из-за кривого оператора присваивания или забытого амперсанта, и, что ещё хуже, забытого delete. А слово знать подразумевает несколько уровне. Можно просто зазубрить - как машина. Можно понимать суть - как специалист. А можно и то и другое - как хакер. Но есть другая проблема - зазубрив, можно очень легко выстрелить себе в ногу использовав что-то не по назначению. Понимая суть сталкиваешься с проблемой частого велосипедостроения, что не лучшим образом сказывается на производительности турда. А хакеров... хакеров мало.
Логика на плюсах - самый частый вариант. Ведь логика с синтаксическим сахаром выходит лаконичной и её редко интересует вопросы реализации, а утечки или незаметны вовсе или проявляются сразу. Да, есть и логические ошибки, но это человеческий фактор, возможен и на Python'е и, тем более, на Haskell.

Добавлено через 2 минуты
Ладно, прекращаем разговор. Он давно вышел за пределы топика. Пока модератор не пришёл и не покалечил кого своим банхаммером.
 Комментарий модератора 
Таких разговоров в тематических разделах вообще вести не нужно. Устное предупреждение !
Поразмять язык можно в общих форумах.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
28.06.2012, 23:08     Как быть и что делать? Трабла с шаблонами
Еще ссылки по теме:

C++ Как через if объявить, что некоторые значения не должны быть равны 0
C++ Тело POST запроса. Как самому узнать, что там должно быть?
C++ Как работать с шаблонами

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
ForEveR
28.06.2012, 23:08     Как быть и что делать? Трабла с шаблонами
  #15

Не по теме:

AnyOne697, Т.к. был вопрос - отвечу. Нет, С++11 не используется (полностью его еще ни один компилер не поддерживает + желательна поддержка хотя бы gcc 4.4, в котором С++11 был реализован крайне мало), зато полноценно используется boost. Плюсы - язык высокого уровня, если его правильно использовать. Ну и на этом действительно стоит закончить)

Yandex
Объявления
28.06.2012, 23:08     Как быть и что делать? Трабла с шаблонами
Ответ Создать тему
Опции темы

Текущее время: 11:21. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru