LINUX.ORG.RU

Ошибка при компиляции примера из учебника Липмана по C++.


0

0

Привет всем. Решил начать изучение C++ по учебнику Липмана(http://tinyurl.com/7887bj5). Там есть один пример, который объясняет использование #ifdef и #endif:

#include <iostream>
using namespace std;
int main()
{
#ifdef DEBUG
cout << "Начало выполнения main()\n";
#endif
string word;
vector<string> text;
while ( cin >> word )
{
#ifdef DEBUG
cout << "Прочитано слово: " << word << "\n";
#endif
text.push_back(word);
}
}
По какой-то причине он не компилируется со следующими ошибками компилятора:
/home/sergey/C++/cel2far/main.cpp: In function ‘int main()’:
/home/sergey/C++/cel2far/main.cpp:9:1: error: ‘vector’ was not declared in this scope
/home/sergey/C++/cel2far/main.cpp:9:14: error: expected primary-expression before ‘>’ token
/home/sergey/C++/cel2far/main.cpp:9:16: error: ‘text’ was not declared in this scope
Я не могу понять, что не так: вроде бы, скопировал четко из учебника, KDevelop никаких явных ошибок не видит.. Буду благодарен, если поможете мне разобраться.


Ответ на: комментарий от anonymous

Это не хелло ворд. Хелло ворд компилится, предыдущий пример тоже компилится.

Vekt
() автор топика

Не подключены необходимые .h файлы: vector и string. Также функция main без аргументов(что есть плохо) и не возвращает значения(вообще плохо).
Я, например, также избегаю using namespace(кто-то когда-то насоветовал), пишу вот так всё:

#include <iostream>
#include <vector>
#include <string>

int main(int argc, char *argv[])
{
#ifdef DEBUG
  std::cout << "Начало выполнения main()\n";
#endif
  std::string word;
  std::vector<std::string> text;
  while ( std::cin >> word )
    {
#ifdef DEBUG
      std::cout << "Прочитано слово: " << word << "\n";
#endif
      text.push_back(word);
    }
  //release allocated memory at string containers:
  text.clear();
  return 0;
}
blinkenlichten
()

емнип, ещё #include <string>

backbone ★★★★★
()
Ответ на: комментарий от blinkenlichten

и string.

Он уже есть в iostream.

Я, например, также избегаю using namespace

Ну и зря. Избегать using нужно только в хидерах.

dmfd
()
Ответ на: комментарий от blinkenlichten

Возврат значения я просто вписать забыл. А что плохого в отсутствии аргументов?(если тупой вопрос, извини, я только вчера учебник открыл, считай, первое знакомство с программированием вообще). А за инклуды спасибо- работает. Видимо, отслеживать их придется самому- в учебнике только о iostream было рассказано.

Vekt
() автор топика
Ответ на: комментарий от blinkenlichten

и не возвращает значения(вообще плохо)

по стандарту функция main неявно вернет 0

theNamelessOne ★★★★★
()

Кстати, если убрать отладочную печать, то весь цикл чтения можно заменить вот на это:

std::vector<std::string> text(std::istream_iterator<std::string>(std::cin), 
                              std::istream_iterator<std::string>());
theNamelessOne ★★★★★
()
Ответ на: комментарий от dmfd

и string.

Он уже есть в iostream.

С С++ я не был бы так уверен :) Порой при сборке всяких тулзов такие бредовые ошибки вылезают..

buddhist ★★★★★
()
Ответ на: комментарий от dmfd

> Я, например, также избегаю using namespace
Ну и зря. Избегать using нужно только в хидерах.

Нет не зря, избегать этого нужно. И самому будет удобнее и нагляднее, и тому, кто будет поддерживать код после вас.

andreyu ★★★★★
()
Ответ на: комментарий от buddhist

С С++ я не был бы так уверен

Строчка #include <string> уже есть в iostream. От вторичного подключения не изменится ровно ничего: сработают header guards же.

dmfd
()
Ответ на: комментарий от andreyu

Я вообще-то всегда так делаю:

void foo()
{
   using something;
   using another_thing;
   using namespace some_namespace;
  
   ...
}

кто будет поддерживать код после вас.

Не позавидуешь этому бедолаге.

dmfd
()
Ответ на: комментарий от buddhist

Тут от неё ничего не зависит. Если только юзер не сделал где-нибудь #define, обманывающий header guards. Но у человека без справки из наркологического диспансера на это такое вряд ли ума хватит.

dmfd
()
Ответ на: комментарий от theNamelessOne

Причем освобождения памяти тут нет. Память в контейнерах надо освобождать так и только если это действительно нужно.

{
  vector<int> src;
  ... fill src here ...
  {
     vector tmp;
     tmp.swap(src);
  }
  ....
}
Reset ★★★★★
()
Ответ на: комментарий от andreyu

Нет не зря

Вот представь какой-нибудь такой код:

    TersoffUmeno(const std::string& prefix)
    {
        using misaki::config::wget; 
        A_ = wget(prefix+".A", 0);
        B_ = wget(prefix+".B", 0);
        lambda_ = wget(prefix+".lambda", 0);
        mu_ = wget(prefix+".mu", 0);
        m_ = wget(prefix+".m", 0);
        c_2_ = pow(wget(prefix+".c", 0), 2);
        d_2_ = pow(wget(prefix+".d", 0), 2);
        h_ = wget(prefix+".h", 0);
        R_ = wget(prefix+".R", 0);
        c_2_d_2_ = c_2_/d_2_;
        mu_m_ = pow(mu_, m_);
    }

без using. Добро же получится.

dmfd
()
Ответ на: комментарий от andreyu

Мне удобно и наглядно ставить using namespace в начале cpp'шника. Каждый раз набирать std::string, std::vector, std::map и т.д. и т.п. напрягает, да и читать код это мешает, так как вместо сути видишь std:: и прочий мусор.

Reset ★★★★★
()
Ответ на: комментарий от blinkenlichten

Кстати, не мог бы ты мне объяснить, как собрать этот код с DEBUG? в учебнике предлагается «CC -DDEBUG», но я make использую...

Vekt
() автор топика
Ответ на: комментарий от dmfd

И более того, представь, тебе придётся писать каждый раз что-то вроде boost::spirit::qi::double_. Нет, вам это какой-то глупый человек рассказал.

dmfd
()
Ответ на: комментарий от Reset

Мне удобно и наглядно ставить using namespace в начале cpp'шника.

Ну каждому свое.

Каждый раз набирать std::string, std::vector, std::map и т.д. и т.п. напрягает, да и читать код это мешает, так как вместо сути видишь std:: и прочий мусор.

А я это вижу как длинное имя функции или метода.

andreyu ★★★★★
()
Ответ на: комментарий от dmfd

ога, а если какое-нибудь апачевское говно подключать, то будет вообще жесть

org::apache::thrift::wtf::stuff::cassandra::Client

Reset ★★★★★
()
Ответ на: комментарий от dmfd

И более того, представь, тебе придётся писать каждый раз что-то вроде boost::spirit::qi::double_. Нет, вам это какой-то глупый человек рассказал.

Вы еще скажите, что буст это хорошо :)

andreyu ★★★★★
()
Ответ на: комментарий от Reset

org::apache::thrift::wtf::stuff::cassandra::Client

Но не выносить же его в самое начало файла. В этом плане вариант dmfd выглядит лучше. Нечто среднее между моим вариантом и вашим.

andreyu ★★★★★
()
Ответ на: комментарий от Reset

А есть альтернативы?

Увы. Но вы ведь ответ и так знаете :)

andreyu ★★★★★
()
Ответ на: комментарий от Vekt

в make это делается очень сложно и для каждого make'а синтаксис будет свой. Для gmake будет что-то типа

#makefile
ifeq ($(debug),1)
CXXFLAGS=-DDEBUG -g -O0
else
CXXFLAGS=-O3
endif

%.o: %.cpp
    g++ -c $(CXXFLAGS) $< -o $@


$ make debug=1 # сборка с отладкой
$ make # сборка без отладки

Reset ★★★★★
()
Последнее исправление: Reset (всего исправлений: 1)
Ответ на: комментарий от schizoid

Что-то все равно тот же результат.

Vekt
() автор топика
Ответ на: комментарий от schizoid

Вопрос снят. «CC» у меня нет, зато есть «c++», и оно замечательно принимает параметр -DDEBUG. Спасибо.

Vekt
() автор топика

вот вопрос, нахуа такой язык, если хелло ворд обсуждается уже третий час

anonymous
()
Ответ на: комментарий от Reset

каждому свое по вкусу.
мне удобно писать так
using namespace::cin;
using namespace::cout;
etc...

Boy_from_Jungle ★★★★
()
Ответ на: комментарий от Vekt

Позоришься ты , скачай работающие примеры на cpp и разбери, учиться надо на работающем коде, а не по бумажке и выдирая функции из справочника.

anonymous
()
Ответ на: комментарий от KennyMinigun

Адские подчёркивания нужны, чтобы поля класса от переменных отличать. Не венгерку же для этого использовать.

dmfd
()
Ответ на: комментарий от KennyMinigun

Это трындец. Вот так кошерно:

class MyClass : public MyAncestor {
public:
     int my_get_method() const;
     void my_set_method(int value);

private:
     int my_class_member_;
};
Reset ★★★★★
()
Ответ на: комментарий от KennyMinigun

ну.. венгерка только отчасти :)

почему бы не использовать ее преимущества в определённых местах

KennyMinigun ★★★★★
()
Ответ на: комментарий от Reset

ну это же как-то совсем по Ц-шному.

// мой вариант почти стырен с Qt гаедлайнов

KennyMinigun ★★★★★
()
Ответ на: комментарий от buddhist

Вот из-за спп-быдлокодеров приходится затариваться всякими бубнами на десять лет вперёд. И то бубны так износятся, что запаса хватит от силы на пятилетку, и то если повезёт.

Hertz ★★★★★
()
Ответ на: комментарий от cdshines

Как я понял, в исходный массив забивается пустой массив, после чего первый массив убивается деструктором при выходе из области видимости, для этого там {}. Костыльненько.

dmfd
()
Ответ на: комментарий от dmfd

А венгерка - http://ompldr.org/vZXFucg/8492e9830e661c9e53f156d7e7a22a3983b007fd.jpg

как говорят тут http://geosoft.no/development/cppstyle.html/

1. Any violation to the guide is allowed if it enhances readability.

The main goal of the recommendation is to improve readability and thereby the understanding and the maintainability and general quality of the code. It is impossible to cover all the specific cases in a general guide and the programmer should be flexible.

А в данном случае что венгерка, что подчёркивание в конце выполняют одну и ту же роль. Но ИМХО - подчёркивание в конце смотрится неуклюже перед операторами. Например

    classMember_ += 1;
    classMember_ = classMember_ + 1;
    classMember_++;

KennyMinigun ★★★★★
()
Ответ на: комментарий от dmfd

Я, наверное, умных книжек не читал, но почему нельзя просто вызвать деструктор явно, если очень приспичило, или не дать просто разурулиться самому при выходе из области видимости? Просто не понимаю смысла, я тупой(

cdshines ★★★★★
()
Ответ на: комментарий от cdshines

почему нельзя просто вызвать деструктор явно

Это было бы удаление вектора, а не его очистка.

Просто не понимаю смысла

Думаю, это потому что внутри вектора может сидеть хитрый аллокатор, который может не отдать память после clear. Но это уже мои домыслы.

dmfd
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.