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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
AnyOne697
134 / 106 / 5
Регистрация: 22.05.2010
Сообщений: 533
#1

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

28.06.2012, 03:53. Просмотров 748. Ответов 14
Метки нет (Все метки)

Литературы по шаблонному программированию в Си++ так много, что поднимать и искать то, что нужно мне довольно долго...

Началось всё с того, что захотелось вывести в поток 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 =)

Заранее спасибо.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
28.06.2012, 03:53
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Как быть и что делать? Трабла с шаблонами (C++):

подскажите что делать при вводимых данных 10 25 и 5 20 программа работает не правильно должна выводить 135 подскажите что делать - C++
Вывод В выходной файл выведите одно число - сколько ударов сделали часы за этот отрезок времени.

Что мне делать или что надо знать перед тем как начать изучение яз.программирования С/С++? - C++
Я пока вообще не умею программировать.Сначала хотел с бейсика или паскаля.Но многие советуют начинать сразу с С/С++.

Как делать, что использовать? - C++
форумчане, недавно приспичило делать многослойный самообучающийся препроцетрон (вроде так называется). хотел бы пройтись по эволюционным...

Подскажите как делать хоть что-нибудь - C++
1. Вычислить значение первой производной функции xN в заданной точке A при заданном значении N. 2. Определить число, полученное...

Подскажите как делать , пожалуйста. Что-нибудь - C++
Хотя бы первые 3. Что получится ?(

джойнер что это за зверь и как его делать - C++
Всем привет, объясните пожалуйста как работает джойнер, по какому принципу, как они склеивают файлы, может у кого исходники есть? Хочу...

14
igorrr37
1647 / 1275 / 133
Регистрация: 21.12.2010
Сообщений: 1,932
Записей в блоге: 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;
}
1
AnyOne697
134 / 106 / 5
Регистрация: 22.05.2010
Сообщений: 533
28.06.2012, 16:37  [ТС] #3
11ая строчка - это какой-то новый синтаксис из C++11? Мне казалось, что там ещё только черновики...

Впрочем, вот http://codepad.org/ZSYXkhd3
Синтаксиса я не знаю, поэтому исправить не могу...
0
igorrr37
1647 / 1275 / 133
Регистрация: 21.12.2010
Сообщений: 1,932
Записей в блоге: 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;
    }
0
ForEveR
В астрале
Эксперт С++
7978 / 4737 / 321
Регистрация: 24.06.2010
Сообщений: 10,543
Завершенные тесты: 3
28.06.2012, 17:08 #5
AnyOne697, Там далеко не черновики. Осваивайте новый стандарт, совет вам.
emplace_back кстати тоже добавлено только в С++11
0
AnyOne697
134 / 106 / 5
Регистрация: 22.05.2010
Сообщений: 533
28.06.2012, 17:17  [ТС] #6
А по поводу принта - какой-то он странный, стоит заметить... Шаманский. Код шамана. Мне до него далеко. Впрочем, работает - значит получиться скопипастить. Спасибо.

Добавлено через 1 минуту
И вот ещё что, кто нибудь даст ссылку на пояснение 11ой строчки?
0
ForEveR
В астрале
Эксперт С++
7978 / 4737 / 321
Регистрация: 24.06.2010
Сообщений: 10,543
Завершенные тесты: 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
2
alsav22
5421 / 4816 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
28.06.2012, 20:14 #8
Цитата Сообщение от ForEveR Посмотреть сообщение
std::vector<int> v = {1,2,3,4,5};
Компилятор эту строчку не пропускает.
0
AnyOne697
134 / 106 / 5
Регистрация: 22.05.2010
Сообщений: 533
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"));
Поясните работу. Уж больно мне понравилось. Хотя здесь и нельзя красиво обрамлять в фигурные скобки (без лишнего пробела), всё же интересно, почему это работает.
0
alsav22
5421 / 4816 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
28.06.2012, 20:34 #10
Цитата Сообщение от AnyOne697 Посмотреть сообщение
С++11 это, не забываем.
Чем это компилировать?
0
ForEveR
В астрале
Эксперт С++
7978 / 4737 / 321
Регистрация: 24.06.2010
Сообщений: 10,543
Завершенные тесты: 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) в последовательность, начало которой указывается в третьем параметре).
1
AnyOne697
134 / 106 / 5
Регистрация: 22.05.2010
Сообщений: 533
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")
я не знаю. Возможно быстрее будет просто вывести в поток. Быстрее и более гибко.
0
ForEveR
В астрале
Эксперт С++
7978 / 4737 / 321
Регистрация: 24.06.2010
Сообщений: 10,543
Завершенные тесты: 3
28.06.2012, 22:14 #13
AnyOne697, Ну... У нас на работе вся логика написана на С++, то есть все ядро системы. Веб на питоне, с биндингом логики из плюсов. Плюсы такой же язык высокого уровня, как и остальные, достаточно выразителен и удобен, если его ЗНАТЬ.

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

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

Добавлено через 2 минуты
Ладно, прекращаем разговор. Он давно вышел за пределы топика. Пока модератор не пришёл и не покалечил кого своим банхаммером.
 Комментарий модератора 
Таких разговоров в тематических разделах вообще вести не нужно. Устное предупреждение !
Поразмять язык можно в общих форумах.
0
ForEveR
28.06.2012, 23:08     Как быть и что делать? Трабла с шаблонами
  #15

Не по теме:

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

0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
28.06.2012, 23:08
Привет! Вот еще темы с ответами:

задачка никак не соображу что да как тут делать - C++
Решить методом простой итерации уравнение вида х=Ф(Х). Очевидное приближение корня находится по формуле Xn=Ф(Xn-1) (на всякий случай n-1...

Как работать с шаблонами - C++
Простенькая програмка, но не компилируеться. Не могу я понять как работать с шаблонами, сколько уже перечитал, все-равно не въеду что не...

Как через if объявить, что некоторые значения не должны быть равны 0 - C++
Мне нужно вычислить предельную сумму(както так) и там есть значения, которые находятся в знаменателе и не должны быть равны 0. Как это...

Тело POST запроса. Как самому узнать, что там должно быть? - C++
Всем здрасти! У меня следующая делема... Нагуглил POST запрос на авторизацию на одноклассниках. Тело POST запроса имеет следующий...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
28.06.2012, 23:08
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru