LINUX.ORG.RU

C++, BOOST_FOREACH и ссылки.


1

1

В std::cout передаются какие-то левые указатели, не могу понять почему.

struct Aaa
{
	typedef std::vector < std::string > Vec;
	Aaa()
	{
		m_vec.push_back( "sobaka" );
		m_vec.push_back( "mendeley" );
	}
////
	Vec m_vec;
};

struct Bbb
{
	Aaa& get(){ return m_aaa; }
////
	Aaa m_aaa;
};


/////////// main() ////////
...
Bbb b_obj;
Aaa &ref_a = b_obj.get();
BOOST_FOREACH( const Aaa::Vec::value_type &_val, ref_a.m_vec )
{
	std::cout << _val << "\n";
}

Ю майд май найт

m_vec.push_back( «sobaka» );
m_vec.push_back( «mendeley» );

замени на emplace_back уже

Aaa& get(){ return m_aaa; }

за это нужно дать тебе по рукам
const Aaa& get() const { return m_aaa; }

BOOST_FOREACH( const Aaa::Vec::value_type &_val, ref_a.m_vec )

хз зачем оно тебе, можно просто
for(const auto& iter : container)
Или тебе именно буст нужен ?

Boy_from_Jungle ★★★★
()

В std::cout передаются какие-то левые указатели

чтоа? Покажи выхлоп.

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

Aaa()

никогда не пиши важную логику в конструкторе. И в деструкторе. Вообще не пользуйся конструкторами и деструкторами, себе дороже.

stevejobs ★★★★☆
()

у меня все работает, valgrind ошибок не выдает.

anonymous
()

Для тех, кто хочет похакать это вместе с ТСом

./src/yauporot.cpp: http://pastebin.com/GECcZVgm

./CMakeLists.txt: http://pastebin.com/edMCUkpu

потом

mkdir ./build
cd build
cmake ..
make
./yauporot

Ожидаемый выхлоп:

[olegchir@archi build]$ make
Scanning dependencies of target yauporot
[100%] Building CXX object CMakeFiles/yauporot.dir/src/yauporot.cpp.o
Linking CXX executable yauporot
[100%] Built target yauporot
[olegchir@archi build]$ ls
CMakeCache.txt  CMakeFiles  cmake_install.cmake  Makefile  yauporot
[olegchir@archi build]$ ./yauporot 
sobaka
mendeley

Это уже линукс,

g++ --version
g++ (GCC) 4.8.1 20130725 (prerelease)
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
stevejobs ★★★★☆
()
Последнее исправление: stevejobs (всего исправлений: 1)

А чо ответы удалил-то? Лучший компромат на крестовиков — их собственные слова )))

У меня с важной логикой в конструкторе всё ништяк. В природе вообще исключения существуют, если чё )

конструктор
исключения
/0

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

Я всё поудалял, т.к. это не по теме. Если ты боишься исключений из конструктора, тогда это ваще песец ацкий срач до утра и не по теме. А хотелось бы по теме.

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

По теме - два отписавшихся на 3 компьютерах с разными ОС, у которых работает. Попробуй мой пример, у тебя заработает? Если да - проблема в твоем проекте, если нет - то проблема в системе вообще.

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

никогда не пиши важную логику в конструкторе. И в деструкторе. Вообще не пользуйся конструкторами и деструкторами, себе дороже.

Ну и бред.

DarkEld3r ★★★★★
()

Эта долбанная софтина есть переломный момент в моей программистической карьере. Придётся выпить йаду для сохранение достоинства, если я сегодня не найду что происходит в компе у меня.

kiverattes ★☆
() автор топика
Ответ на: комментарий от DarkEld3r

нужно акуратно контролировать что нужно самостоятельно деструктить, если кидаются исключения. Также нужно выпасывать какие функцыи что вызывает конструктор могут кинуть исключения.

Багов можно наловить без проблем.

А в C++11 исключения в деструкторах ведут к внезапному окончанию жизни программы.

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

Нашёл ошибку. Она была за рамками приведённого кода. Оказывается в процессе прохода по вектору этот вектор был изменён.

То есть, картина такая:

BOOST_FOREACH запоминал два итератора - it = begin(), ite = end() и шёл по вектору итератором it. Пока он шёл, вектор сильно менялся и итераторы протухали. При следующей попытке разименования вектора (протухшего) получалась моя ошибка.

Меняющего кода в первоначальном посте нет. Я его случайно выкинул, выкидывая из цикла всё «несущественное».

P.S. Я точно не знаю как работает BOOST_FOREACH, но как по-другому представить не могу. Определение у него суровое, моск взрывается от смеси шаблонов с макросами, но упоминание for и «iterator» я там видел )

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

emplace_back

он ради foreach тянет буст, о С++11 в его коде не слыхали.

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

никогда не пиши важную логику в конструкторе. И в деструкторе

пока логика не бросает сигнал или исключение то хоть войну и мир пиши. единственный минус - время инстанцирования, если критично.

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

Оказывается в процессе прохода по вектору этот вектор был изменён.

ты хоть понял почему он менялся?
а вообще у тебя там думаю UB

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

Да понял... Код пробегал по настройкам, прочитанным из файла и хранящимся в векторе и добавлял элементы управления в тулбар, а тулбар при каждом своём изменении сохранял себя в тот же объект настроек, снося там всё предыдущее и портя векторы бегающему коду.

Чё такое UB? Копец, старый стал, не понимаю молодёжь уже.

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

Ну дык... когда левые указатели валятся, оно уже какое-то всё undefined )

kiverattes ★☆
() автор топика
Ответ на: комментарий от dzidzitop

Меня больше конструкторы интересовали.

А в C++11 исключения в деструкторах ведут к внезапному окончанию жизни программы.

Это не (совсем) так. Просто все деструкторы в С++ теперь неявно обьявлены как noexcept. Никто не запрещает обьявить деструктор как noexcept(false). А дальше всё как в С++98.

Плюс две мелкие придирки:

Во первых, не «внезапное окончание жизни программы, а вызов std::terminate. На который можно повесить свой обработчик.

Во вторых, само по себе исключение в деструкторе ни к чему не приводит (если оно обрабатывается внутри).

Но меня больше конструкторы интересовали.

нужно акуратно контролировать что нужно самостоятельно деструктить, если кидаются исключения

Зачем?

Также нужно выпасывать какие функцыи что вызывает конструктор могут кинуть исключения.

Зачем?

Багов можно наловить без проблем.

Это можно сделать вообще на ровном месте (и на любом языке, при достаточной кривизне рук).

Но я что-то не увидел альтернативы. Неужели двухфазная инициализация? И чем это лучше? Все проблемы остаются (точно так же нужно „нужно выпасывать какие функцыи что вызывает конструктор могут кинуть исключения“ если мы не хотим вообще бросать исключения) плюс теперь у нас обьект ещё может оказаться в непроинициализированном состоянии. В определённых случаях она нужна, но далеко не везде.

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

про noexcept(false) не знал, спасібо. Остальное подразумевалось.

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

struct Foo
{
    int *x;

    Foo()
    {
         x = new int(0);
         throw "whatever";
         // x is not deleted.
         // destructor is not invoked
    }

    ~Foo()
    {
        delete x;
    }
}
anonymous
()
Ответ на: комментарий от DarkEld3r

Неужели двухфазная инициализация?

Скорее нет. Просто нужно внимательно кодить + гонять детекторы memory leaks.

И чем это лучше?

Лучше только тем, что деструктор обьекта будет вызван.

dzidzitop

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

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

std::unique_ptr

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

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

Ясное дело. Поэтому писать надо так:

struct Foo
{
    std::unique_ptr<int> x;

    Foo()
        : x(new int(0))
    {
         throw "whatever";
         // x is deleted now.
    }

    ~Foo()
    {}
}

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

Лучше только тем, что деструктор обьекта будет вызван.

Если писать правильно (RAII наше всё), то это просто не потребуется.

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

не пользуйся конструкторами и деструкторами

Люблю С++.

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