LINUX.ORG.RU

C++ с «умными» указателями и портирование кода.


0

0

Доброго времени суток! Не могу найти достаточно внятной информации по так называемых - "умным" указателям, как их окрестил какой-то автор. Но это пол беды. Вторая половина беды - заключается в том, что g++ не компилирует такой код, с "умными" указателями.

main.cpp:
#include "a.h"

int main()
{ return 0; }

a.h:
namespace A {

typedef vector<string> StringList;
typedef StringList::iterator StringIter;
typedef StringList::const_iterator StringIterC;

typedef pair<string, string> StringPair;
typedef vector<StringPair> StringPairList;
typedef StringPairList::iterator StringPairIter;

typedef std::tr1::unordered_map<string, string> StringMap;
typedef StringMap::iterator StringMapIter;

typedef std::tr1::unordered_set<string> StringSet;
typedef StringSet::iterator StringSetIter;

typedef vector<wstring> WStringList;
typedef WStringList::iterator WStringIter;typedef pair<wstring, wstring> WStringPair;
typedef WStringList::const_iterator WStringIterC;
typedef vector<WStringPair> WStringPairList;
typedef WStringPairList::iterator WStringPairIter;
}

Если не трудно - объясните принцип работы таких указателей, и как можно портировать этот кусок кода.

P.S. GCC-4.1.2. Что касается tr1 - ругается, хотя установлена последняя boost.


hto budet hidery propisyvat'?

-------------8<------------------ #include <string> #include <vector> #include <map>

using namespace std;

------------->8------------------

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

hto budet hidery propisyvat'?

-------------8<------------------
#include <string>
#include <vector>
#include <map>

using namespace std;

------------->8------------------

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

хидеры просто пропустил для экономии места в посте. Разумеется все перечисленные выше хидеры были прописаны. Только компилятор ругается все равно...

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

громадная портянка, но ругается однотипно в таком ключе:

a.h:48: ошибка: expected initializer before '<' token
a.h:49: ошибка: 'WStringMap' не был декларирован
a.h:49: ошибка: expected initializer before 'WStringMapIter'

на месте этих строчек:
typedef unordered_map<wstring, wstring> WStringMap; typedef WStringMap::iterator WStringMapIter;

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

Может, у тебя wstring нет...

попробуй скомпилировать файл, состоящий только из

typedef unordered_map<wstring, wstring> WStringMap;

typedef WStringMap::iterator WStringMapIter;

Не получится - замени wstring на string и попробуй еще раз - так ты по крайней мере поймешь, с чем связана ошибка.

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

Спасибо за помощь, кажется я нашел в какую сторону копать - дальше будет проще, да и опыту наберусь.

Но вот может все-таки объясните как работают такие структуры:
typedef std::tr1::shared_ptr<FileData> FileDataPtr;

эквивалентно ли это - чему-нибудь вроде:
typedef FileData *FileDataPtr;

или
typedef pair<string, string> StringPair;
и
typedef WStringPairList::iterator WStringPairIter;

не могу найти вменяемую информацию по теме. Приветствуются тыкание носом в ссылки и, конечно, объянение процесса =)

Заранее спасибо

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

shared_ptr - это указатель с подсчетом ссылок. Вещь концептуально несложная, но с кучей интересных деталей реализации. Является частью буста (www.boost.org) - в тамошней доке описана.

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

> Но вот может все-таки объясните как работают такие структуры:
> typedef std::tr1::shared_ptr<FileData> FileDataPtr;

> эквивалентно ли это - чему-нибудь вроде:
> typedef FileData *FileDataPtr;

Практически эквивалентно. За исключением того, что shared_ptr будет сам объект уничтожать, когда на него последний объект типа FileDataPtr перестанет указывать. Ну и присваивание нельзя делать, нужно FileDataPtrObjA(FileDataPtrObjB) делать.

Читать на boost.org, там достаточно внятно написано.

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

>>shared_ptr - это указатель с подсчетом ссылок. Вещь концептуально несложная, но с кучей интересных деталей реализации. Является частью буста (www.boost.org) - в тамошней доке описана.

Благадарю

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

вот на такой кусок кода в header

class B : public IOStream {
public:
B();
private:
struct S {
int i;
};

typedef std::tr1::shared_ptr<S> SPtr;

SPtr test;
};

вот так ругается:

b.h:32: ошибка: ISO C++ запрещает декларации 'shared_ptr' без типа
b.h:32: ошибка: для typedef-имени недопустимы квалификаторы классов
b.h:32: ошибка: expected ';' before '<' token
b.h:34: ошибка: 'SPtr' does not name a type

хотя, ИМХО, все верно. Или я что-то неправильно понял об этом shared_ptr? На сколько изменится смысл, если
вместо:
typedef std::tr1::shared_ptr<S> SPtr;
написать:
typedef S *SPtr; // Так работает

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

>хидеры просто пропустил для экономии места в посте. Разумеется все >перечисленные выше хидеры были прописаны. Только компилятор ругается >все равно...

не экономьте, приведите полный код,
который (а) должен компилиться, (б) не компилиться,

пока что все указанные вами ошибки, могут произойти только
из-за того, что вы не сделали нужный #include

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

> typedef std::tr1::shared_ptr<S> SPtr;

> b.h:32: ошибка: ISO C++ запрещает декларации 'shared_ptr' без типа

у тебя явно не включен заголовочный файл с shared_ptr. Или неправильно указан namespace.

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

>> > typedef std::tr1::shared_ptr<S> SPtr;

>> > b.h:32: ошибка: ISO C++ запрещает декларации 'shared_ptr' без типа

>>у тебя явно не включен заголовочный файл с shared_ptr. Или неправильно указан namespace.

используется using namespace std;
А какой надо включить заголовочный файл с shared_ptr?

Привожу полный кусок кода хидера:

#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include <memory.h>
#include <sys/types.h>
#include <time.h>
#include <locale.h>

#include <algorithm>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <deque>
#include <list>
#include <utility>
#include <functional>
#include <memory>
#include <numeric>
#include <limits>

#include <tr1/unordered_set>
#include <tr1/unordered_map>


using namespace std;

namespace GGG {

/** A file used by multiple writers */
class C : public IOStream {
public:
C();

private:
struct S {
int i;
};

typedef std::tr1::shared_ptr<S> SPtr;

SPtr sp;
};

}

в свою очередь namespace GGG декларируется так:
namespace GGG {
using namespace std;
using namespace std::tr1;
}
в чем ошибка, если ругается, как говорилось выше...

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

> А какой надо включить заголовочный файл с shared_ptr?

Как уже сказано, shared_ptr - это часть Буста. Точнее говоря, он был частью буста, а потом перебрался в tr1, AFAIK. Если ты переносишь код с новой версии компилятора (в которой tr1 включает в себя shared_ptr) на старую (в которой shared_ptr нет вообще), у тебя будут как раз такие ошибки.

В бусте - #include <boost/shared_ptr.hpp>

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

>> В бусте - #include <boost/shared_ptr.hpp>

делал так. файл такой существует (видимо для поддрежки предыдущих версий), но результат тот же. ни байта не меняется в его error_messages.

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

>> #include <boost/shared_ptr.hpp> >> >>typedef boost::shared_ptr<FooBar> FooBarPtr;

Спасибо, анонимус, помогло. Странно, что я так не додумался =)

Хотя в крайней мере странно: boost - последняя версия из svn. tr1 - уже стандарт де факто, со след года - оффициальный стандарт. а напрямую не работает через std::tr1, надо ему, видите ли, boost::...

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

>> >> В бусте - #include <boost/shared_ptr.hpp> >> >> >делал так. >> >> Но при этом ты _не_ заменил std::tr1::shared_ptr на boost::shared_ptr, ага?

Навеяло... "Бывает, что ищешь ошибку программе упорно и долго и не можешь ее найти. Просишь помощи... И когда 10 пар глаз пялются в один монитор, ты понимаешь - где ошибся, но боишься об этом сказать, потому что ошибка ОЧЕНЬ глупая" =)

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

C++ for Real Programmers by Jeff Alger (Author)

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

>а напрямую не работает через std::tr1, надо ему, видите ли, boost::...

Ну это нормально. В Стандарте чётко написано: расширять пространство имён std _нельзя_.

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

>#include <ctype.h>
>#include <stdio.h>
>#include <stdarg.h>
>#include <memory.h>
>#include <sys/types.h>
>#include <time.h>
>#include <locale.h>

Обычно в книжках рекомендуют писАть ctype, cstdio, cstdlib, ctime и т.д....

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