crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )


  Ответ в Какает непонятная проблема с boost::bind
Введите ваше имя
Подтвердите код

Введите в поле код из 6 символов, отображенных в виде изображения. Если вы не можете прочитать код с изображения, нажмите на изображение для генерации нового кода.
 

Опции сообщения
 Включить смайлы?
Иконки сообщения
(Опционально)
                                
                                
  [ Без иконки ]
 


Последние 10 сообщений [ в обратном порядке ]
Гость_Алексей_* Дата 6.7.2012, 21:15
  Студию скачал где то пол года назат, с сайта Microsoft,
Visual Studio Express 2010, Версия 10.0.40219.1 SP1Rel тобиш бесплатная версия
версию и название компилятора чёт не нашел где глянуть...

не думаю что они устаревают так быстро, хотя может из-за того что express версия, такие проблемы.....
Iron Bug Дата 6.7.2012, 20:34
  это может быть проблемой компилятора:
Цитата
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)

старые компиляторы не поддерживают частичные списки параметров.
Гость_Алексей_* Дата 6.7.2012, 18:06
  Проблема была решена, (вчера помоем форум упал, поэтому затянул с ответом :) )
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 Дата 6.7.2012, 7:49
  если метод не виртуальный и объект не разрушен в момент вызова сигнала, то должно работать.
например, вот это работает без проблем:
#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. в студии это тоже работает - только что проверила.
Гость_Алексей_* Дата 5.7.2012, 9:33
  чёт забыл ещё отписать момент,
сделал функцию void Test::init(void) в ней вызываю ту строчку... результат тот же.... конструктор не причём

ПОИСК ПРОБЛЕМЫ ПРОДОЛЖАЕТСЯ !!!
Гость_Алексей_* Дата 5.7.2012, 8:29
  Мысли в слух...

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

не вижу проблемы (по крайней мере явной) использовать boost::bind(&class::funct, this); в конструкторе.... чисто по логике
и как видно иногда все работает... но не всегда) мож в чём другом проблема?
Гость_Алексей_* Дата 5.7.2012, 8:02
  А вот теперь возник вопрос :)
Я походу достаю детскими вопросами, ну я не могу понять, если таблиц нет как я связал сигнал со слотов в этом случае, из конструктора....

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()
{

}


код работает, почему?)
Гость_Алексей_* Дата 5.7.2012, 7:46
  Ясно....
уже не первый раз наезжаю на похожие грабли, правд немного в другом направление..... нечему жизнь не учит :)

ну лан вобщем спасибо за развёрнутый ответ Iron Bug
и тебе спасиб Алексей1153
Iron Bug Дата 5.7.2012, 7:34
  bind тут ни при чём. Алексей1153 правильно сказал, что вызов нестатической функции в конструкторе в С++ запрещён в принципе. что вызывать-то, если самого объекта ещё нет? нет виртуальной таблицы - нет и адреса функции. и пофиг, что туда передавать. поиск адреса идёт через виртуальные таблицы, которых во время работы конструктора ещё нет.
конструктору оставь его работу по инициализации, а потом уже вызывай что хочешь в какой-то отдельной функции.
Гость_Алексей_* Дата 5.7.2012, 6:36
 
Цитата(Алексей1153 @ 5.7.2012, 6:00) *
что-то мне подсказывает, что функция должна быть статической


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



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


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


и насчёт последней цитаты, читай неправильные слова, с правильным ударением :)
Просмотр темы полностью (откроется в новом окне)
RSS Текстовая версия Сейчас: 20.8.2019, 22:12