Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Какает непонятная проблема с boost::bind
Форум на CrossPlatform.RU > Библиотеки > boost
Гость_Алексей_*
Всем привет, особенно Iron Bug...


Вот на этой строчке выдает ошибку... (строчка вызывается в конструкторе Test)
CollisionBeginContact function = boost::bind(&Test::s1, this, _1)();


Ошибка 6 error C1903: не удается восстановить после предыдущих ошибок; остановка компиляции d:\code\boost_1_49_0\boost\bind\bind.hpp 69
Ошибка 3 error C2039: result_type: не является членом "`global namespace'" d:\code\boost_1_49_0\boost\bind\bind.hpp 69
Ошибка 4 error C2146: синтаксическая ошибка: отсутствие ";" перед идентификатором "type" d:\code\boost_1_49_0\boost\bind\bind.hpp 69
Ошибка 5 error C2208: boost::_bi::type: нет членов, определенных с помощью этого типа d:\code\boost_1_49_0\boost\bind\bind.hpp 69
Ошибка 2 error C2825: F: должен представлять класс или пространство имен с последующим "::" d:\code\boost_1_49_0\boost\bind\bind.hpp 69


Вывод лога построения
Раскрывающийся текст

1>------ Построение начато: проект: PhusModelTest, Конфигурация: Debug Win32 ------
1> Test.cpp
1>d:\code\project\phusmodeltest\phusmodeltest\test.cpp(28): warning C4305: аргумент: усечение из "double" к "float32"
1>d:\code\boost_1_49_0\boost\bind\bind.hpp(69): error C2825: F: должен представлять класс или пространство имен с последующим "::"
1> d:\code\boost_1_49_0\boost\bind\bind_template.hpp(15): см. ссылку на создание экземпляров класса шаблон при компиляции "boost::_bi::result_traits<R,F>"
1> with
1> [
1> R=boost::_bi::unspecified,
1> F=void (__thiscall Test::* )(b2Fixture *,b2Fixture *,b2Contact *)
1> ]
1> d:\code\project\phusmodeltest\phusmodeltest\test.cpp(50): см. ссылку на создание экземпляров класса шаблон при компиляции "boost::_bi::bind_t<R,F,L>"
1> with
1> [
1> R=boost::_bi::unspecified,
1> F=void (__thiscall Test::* )(b2Fixture *,b2Fixture *,b2Contact *),
1> L=boost::_bi::list2<boost::_bi::value<Test *>,boost::arg<1>>
1> ]
1>d:\code\boost_1_49_0\boost\bind\bind.hpp(69): error C2039: result_type: не является членом "`global namespace'"
1>d:\code\boost_1_49_0\boost\bind\bind.hpp(69): error C2146: синтаксическая ошибка: отсутствие ";" перед идентификатором "type"
1>d:\code\boost_1_49_0\boost\bind\bind.hpp(69): error C2208: boost::_bi::type: нет членов, определенных с помощью этого типа
1>d:\code\boost_1_49_0\boost\bind\bind.hpp(69): fatal error C1903: не удается восстановить после предыдущих ошибок; остановка компиляции
1> ContactListener.cpp
1> Создание кода...
========== Построение: успешно: 0, с ошибками: 1, без изменений: 0, пропущено: 0 ==========


или так (тут ошибки выдаются немного иначе)
CollisionBeginContact function = boost::bind(&Test::s1, this)();

Ошибка 9 error C2298: return: недопустимая операция с указателем на выражение функции-члена d:\code\boost_1_49_0\boost\bind\mem_fn.hpp 342

Вывод лога построения
Раскрывающийся текст

1>------ Построение начато: проект: PhusModelTest, Конфигурация: Debug Win32 ------
1> Test.cpp
1>d:\code\project\phusmodeltest\phusmodeltest\test.cpp(28): warning C4305: аргумент: усечение из "double" к "float32"
1>d:\code\boost_1_49_0\boost\bind\mem_fn.hpp(318): warning C4180: квалификатор, примененный к типу-функции, не имеет смысла; пропуск
1> d:\code\boost_1_49_0\boost\bind\bind_template.hpp(344): см. ссылку на создание экземпляров класса шаблон при компиляции "boost::_mfi::Dm<R,T>"
1> with
1> [
1> R=void (b2Fixture *,b2Fixture *,b2Contact *),
1> T=Test
1> ]
1> d:\code\project\phusmodeltest\phusmodeltest\test.cpp(50): см. ссылку на создание экземпляров класса шаблон при компиляции "boost::_bi::bind_t<R,F,L>"
1> with
1> [
1> R=void (&)(b2Fixture *,b2Fixture *,b2Contact *),
1> F=boost::_mfi::Dm<void (b2Fixture *,b2Fixture *,b2Contact *),Test>,
1> L=boost::_bi::list1<boost::_bi::value<Test *>>
1> ]
1>d:\code\boost_1_49_0\boost\bind\mem_fn.hpp(326): warning C4180: квалификатор, примененный к типу-функции, не имеет смысла; пропуск
1>d:\code\boost_1_49_0\boost\bind\mem_fn.hpp(331): warning C4180: квалификатор, примененный к типу-функции, не имеет смысла; пропуск
1>d:\code\boost_1_49_0\boost\bind\mem_fn.hpp(345): warning C4180: квалификатор, примененный к типу-функции, не имеет смысла; пропуск
1>d:\code\boost_1_49_0\boost\bind\mem_fn.hpp(350): warning C4180: квалификатор, примененный к типу-функции, не имеет смысла; пропуск
1>d:\code\boost_1_49_0\boost\bind\mem_fn.hpp(362): warning C4180: квалификатор, примененный к типу-функции, не имеет смысла; пропуск
1>d:\code\project\phusmodeltest\phusmodeltest\test.cpp(65): warning C4244: аргумент: преобразование "int" в "float32", возможна потеря данных
1>d:\code\boost_1_49_0\boost\bind\mem_fn.hpp(342): error C2298: return: недопустимая операция с указателем на выражение функции-члена
1> d:\code\boost_1_49_0\boost\bind\mem_fn.hpp(341): при компиляции функции-члена "void (&boost::_mfi::Dm<R,T>::operator ()(T *) const)" класса шаблон
1> with
1> [
1> R=void (b2Fixture *,b2Fixture *,b2Contact *),
1> T=Test
1> ]
1> d:\code\boost_1_49_0\boost\bind\bind_template.hpp(344): см. ссылку на создание экземпляров класса шаблон при компиляции "boost::_mfi::Dm<R,T>"
1> with
1> [
1> R=void (b2Fixture *,b2Fixture *,b2Contact *),
1> T=Test
1> ]
1> d:\code\project\phusmodeltest\phusmodeltest\test.cpp(50): см. ссылку на создание экземпляров класса шаблон при компиляции "boost::_bi::bind_t<R,F,L>"
1> with
1> [
1> R=void (&)(b2Fixture *,b2Fixture *,b2Contact *),
1> F=boost::_mfi::Dm<void (b2Fixture *,b2Fixture *,b2Contact *),Test>,
1> L=boost::_bi::list1<boost::_bi::value<Test *>>
1> ]
========== Построение: успешно: 0, с ошибками: 1, без изменений: 0, пропущено: 0 ==========



вырезки кода:
typedef boost::function<void(b2Fixture* this_fixture, b2Fixture* front_fixture, b2Contact* contact)> CollisionBeginContact;

....

void Test::s1(b2Fixture* this_fixture, b2Fixture* front_fixture, b2Contact* contact)
{
    std::cout << "CollisionBeginContact: " << std::endl;
}



Чувствую что жёско туплю ща, но нечего не приходит в голову....
Жду подсказки :)
Алексей1153
что-то мне подсказывает, что функция должна быть статической :)

а ещё - обращай внимание на warning'и , там много интересного написано бывает

Цитата(Алексей1153 @ 5.7.2012, 9:00) *
Какает

:D
Гость_Алексей_*
Цитата(Алексей1153 @ 5.7.2012, 6:00) *
что-то мне подсказывает, что функция должна быть статической


неа, можно не только для статик функций.... яж не просто так this туда передаю....



Цитата(Алексей1153 @ 5.7.2012, 6:00) *
а ещё - обращай внимание на warning'и , там много интересного написано бывает


усечение double в float32 это печально, но там так и задумано.... :)


и насчёт последней цитаты, читай неправильные слова, с правильным ударением :)
Iron Bug
bind тут ни при чём. Алексей1153 правильно сказал, что вызов нестатической функции в конструкторе в С++ запрещён в принципе. что вызывать-то, если самого объекта ещё нет? нет виртуальной таблицы - нет и адреса функции. и пофиг, что туда передавать. поиск адреса идёт через виртуальные таблицы, которых во время работы конструктора ещё нет.
конструктору оставь его работу по инициализации, а потом уже вызывай что хочешь в какой-то отдельной функции.
Гость_Алексей_*
Ясно....
уже не первый раз наезжаю на похожие грабли, правд немного в другом направление..... нечему жизнь не учит :)

ну лан вобщем спасибо за развёрнутый ответ Iron Bug
и тебе спасиб Алексей1153
Гость_Алексей_*
А вот теперь возник вопрос :)
Я походу достаю детскими вопросами, ну я не могу понять, если таблиц нет как я связал сигнал со слотов в этом случае, из конструктора....

Humanoid::Humanoid(boost::signal<void ()>& signalPostStep, const b2Vec2& pos, float32 width, float32 height)
{
    signalPostStep.connect(boost::bind(&Humanoid::postStep, this));
}

//no static
void Humanoid::postStep()
{

}


код работает, почему?)
Гость_Алексей_*
Мысли в слух...

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

не вижу проблемы (по крайней мере явной) использовать boost::bind(&class::funct, this); в конструкторе.... чисто по логике
и как видно иногда все работает... но не всегда) мож в чём другом проблема?
Гость_Алексей_*
чёт забыл ещё отписать момент,
сделал функцию void Test::init(void) в ней вызываю ту строчку... результат тот же.... конструктор не причём

ПОИСК ПРОБЛЕМЫ ПРОДОЛЖАЕТСЯ !!!
Iron Bug
если метод не виртуальный и объект не разрушен в момент вызова сигнала, то должно работать.
например, вот это работает без проблем:
#include <iostream>
#include <boost/bind.hpp>
#include <boost/signal.hpp>
#include <boost/thread.hpp>

using namespace std;
using namespace boost;

class A
{
    boost::condition_variable *_pcond;
    boost::mutex *_pmt;
    int *_pcounter;

    public:
    A(signal<void()>&sg,boost::condition_variable *pcond, boost::mutex *pmt, int *pcounter): _pcond(pcond), _pmt(pmt), _pcounter(pcounter)
    {
        sg.connect(boost::bind(&A::foo,this));
    }
    void func(signal<void()>&sg)
    {
        sg.connect(boost::bind(&A::foo,this));
    }
    void foo()
    {
        cout << "hello there! " << *_pcounter << endl;
        {
            boost::lock_guard<boost::mutex> lock(*_pmt);
            (*_pcounter)++;
        }
        _pcond->notify_one();
    }
};

int main()
{
    boost::condition_variable cond;
    boost::mutex mt;
    int counter = 0;

    signal<void()> sg;
    A a(sg,&cond,&mt,&counter);
    a.func(sg);
    sg();

    boost::unique_lock<boost::mutex> lock(mt);
    while(counter < 2)
    {
        cond.wait(lock);
    }

    cout << "done" << endl;
    return 0;
}


возможно, у тебя в момент вызова сигнала сам объект уже мог и не существовать.
я поставила синхронизацию (через conditional_variable), чтобы убедиться, что обработка сигналов завершена к моменту выхода из главной функции (когда объект a будет разрушен).
ну и компилиться это должно с мультипоточностью, естественно. иначе не будет работать.


а, да... если это всё ещё проблемы компиляции, то какой компилятор юзаешь?
в стандарте С++11 оператор bind стал встроенным в стандартные библиотеки и теперь у многих компиляторов есть по два варианта bind: в бусте и у себя, в стандартной поддержке. так что нужно явно указывать, какой ты бинд юзаешь. и лучше взять последний буст, ибо в каком-то из предыдущих были жёсткие глюки именно с bind, хотя это было довольно давно уже, я думаю, полгода назад, как минимум, когда стандарт только вышел.
я это собирала под mingw. ща попробую в студии собрать. возможно, там может быть конфликт пространств. тогда принудительно писать boost::bind везде.

P.S. в студии это тоже работает - только что проверила.
Гость_Алексей_*
Проблема была решена, (вчера помоем форум упал, поэтому затянул с ответом :) )
bind оказался тоже не причём, когда я приравниваю к функтору то происходит этот косяк...
если функция без параметров то все работает как надо..... иначе печаль.... ну я прописал плейсхолдеры(вроде так называются _1, _2, _3 .. _n) равные кол-ву параметров в функторе.... и все заработало

Было
typedef boost::function<void(b2Fixture* this_fixture, b2Fixture* front_fixture, b2Contact* contact)> CollisionBeginContact;
CollisionBeginContact function = boost::bind(&Test::s1, this);

а надо было (рабочий вариант)
CollisionBeginContact function = boost::bind(&Test::s1, this, _1, _2, _3);

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

Может я не до конца понимаю необходимость плейсхолдеров и каким боком они нужны здесь, когда я работал с сетью и через bind кидал функтор для обратного вызова при происхождение каких либо событий, я не прописывал плейсхолдеры....
в общем проблема решена, теперь пытаюсь понять почему :)


Цитата
в стандарте С++11 оператор bind стал встроенным в стандартные библиотеки и теперь у многих компиляторов есть по два варианта bind: в бусте и у себя, в стандартной поддержке. так что нужно явно указывать, какой ты бинд юзаешь. и лучше взять последний буст, ибо в каком-то из предыдущих были жёсткие глюки именно с bind, хотя это было довольно давно уже, я думаю, полгода назад, как минимум, когда стандарт только вышел.


Не знал, спасибо за информацию....
У меня boost 1.49.0, пока не успел обновить его до boost 1.50.0, да и мне кажется в этом нет особой необходимости.....
Iron Bug
это может быть проблемой компилятора:
Цитата
Inappropriate use of bind<R>(f, ...)

The bind<R>(f, a1, a2, ..., aN) form supports arbitrary function objects.

It is possible (but not recommended) to use this form with functions or member function pointers, but only on compilers that support partial ordering. In particular, MSVC up to version 7.0 does not fully support this syntax for functions and member function pointers.

(http://www.boost.org/doc/libs/1_49_0/libs/bind/bind.html#Q_forms)

старые компиляторы не поддерживают частичные списки параметров.
Гость_Алексей_*
Студию скачал где то пол года назат, с сайта Microsoft,
Visual Studio Express 2010, Версия 10.0.40219.1 SP1Rel тобиш бесплатная версия
версию и название компилятора чёт не нашел где глянуть...

не думаю что они устаревают так быстро, хотя может из-за того что express версия, такие проблемы.....
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Форум IP.Board © 2001-2019 IPS, Inc.