Хобрук: Ваш путь к мастерству в программировании

double boost::bind вызывает ошибку времени компиляции

Следующий код дает ошибку компиляции, вызванную строкой 17:

#include <boost/bind.hpp>
#include <boost/function.hpp>

void func()
{}

class A{
public:

    template <typename T>
    static void foo(T const& arg){}

    template <typename T>
    void bar(T const& arg){
        boost::bind(&A::foo<T>, arg);  //OK
        boost::function<T> functor1 = boost::bind(func); //OK
        boost::function<T> functor2 = boost::bind(&A::foo<T>, arg); //ERROR, LINE 17
    }
};

int main()
{
    A obj1;
    obj1.bar(func);
}

Вопрос в том, каким должен быть прототип functor2 в строке 17?
Если я действительно хочу, чтобы прототип functor2 был "boost::function‹void()›, как заставить boost::bind возвращать такие тип?

Ошибка компиляции:usr/include/boost/bind/bind.hpp:253: error: invalid initialization of reference of type 'void (&)()' from expression of type 'void (*)()'
Что это значит?


  • Попробуйте boost::function‹void (T const&) › functor2 = boost::bind(&A::foo‹T›, arg); 11.04.2012
  • Это не работает. потому что T уже является void(*)(). 12.04.2012

Ответы:


1

foo(T const& arg) принимает ссылочный аргумент. Чтобы передать ссылочный аргумент через boost::bind, вам нужно обернуть его boost::ref.

boost::function<T> functor2 = boost::bind(&A::foo<T>, boost::ref(arg));
01.10.2012

2

Взгляните на Каков тип возврата boost::bind?

Короче, я бы просто написал

auto functor2 = boost::bind(&A::foo<T>, arg);

и скомпилируйте его с помощью gcc 4.6+ или gcc 4.4 с опцией --std=gnu++0x.

11.04.2012
  • к сожалению, я не могу включить опцию cpp0x. Этот пример кода выше упрощен и минимизирован по сравнению с реальным кодом проекта. Обвязка сборки исправлена ​​и не может использовать новый стандарт. 12.04.2012

  • 3

    У меня нет опыта работы с привязкой, но разве вам обычно не нужен экземпляр класса, для которого вы вызываете функцию-член? Если вы не включили его в привязку, вам нужно будет включить его на сайте вызова. Используя auto для моего примера (я читал выше, что вы не можете его использовать, но я буду для краткости), я повторно реализую ваш метод A::bar():

    void bar(T const& arg){
        auto barebones = boost::bind(&A::foo<T>, arg);
        // OR
        auto barebones = boost::bind(&A::foo<T>, _1, arg);
        barebones(this); // Need an instance, or a pointer to an instance of A
        boost::function<T> functor1 = boost::bind(func); // OK because func is a bare function with no arguments
        boost::function<T> functor2 = boost::bind(&A::foo<T>, this, arg); // betting that would work
        functor2(); // with my modification, I think that'll work.
    }
    

    Вам МОЖЕТ понадобиться синтаксис _1, чтобы сказать, что первый аргумент занимает это место, или он может работать без него. Я не уверен на 100% (не компилировал его), но основываясь на документации на сайте boost (boost связать документ, увеличить mem_fn doc) я думаю, что это то, что происходит.

    Зачем скомпилирована первая часть, я не знаю. Это заставляет меня подозревать, что исходный синтаксис в порядке, но вам нужно передать экземпляр класса. Если вы ищете «голый» вызываемый объект, которому не нужны дополнительные аргументы, вам нужно передать экземпляр (или указатель на него, или интеллектуальный указатель на один) при привязке.

    Если у вас возникли проблемы с выводом типов, попробуйте макрос BOOST_AUTO(), если можете. ссылка на документ.

    11.04.2012
    Новые материалы

    Учебные заметки JavaScript Object Oriented Labs
    Вот моя седьмая неделя обучения программированию. После ruby ​​и его фреймворка rails я начал изучать самый популярный язык интерфейса — javascript. В отличие от ruby, javascript — это более..

    Разбор строк запроса в vue.js
    Иногда вам нужно получить данные из строк запроса, в этой статье показано, как это сделать. В жизни каждого дизайнера/разработчика наступает момент, когда им необходимо беспрепятственно..

    Предсказание моей следующей любимой книги 📚 Благодаря данным Goodreads и машинному обучению 👨‍💻
    «Если вы не любите читать, значит, вы не нашли нужную книгу». - J.K. Роулинг Эта статья сильно отличается от тех, к которым вы, возможно, привыкли . Мне очень понравилось поработать над..

    Основы принципов S.O.L.I.D, Javascript, Git и NoSQL
    каковы принципы S.O.L.I.D? Принципы SOLID призваны помочь разработчикам создавать надежные, удобные в сопровождении приложения. мы видим пять ключевых принципов. Принципы SOLID были разработаны..

    Как настроить Selenium в проекте Angular
    Угловой | Селен Как настроить Selenium в проекте Angular Держите свое приложение Angular и тесты Selenium в одной рабочей области и запускайте их с помощью Mocha. В этой статье мы..

    Аргументы прогрессивного улучшения почти всегда упускают суть
    В наши дни в кругах веб-разработчиков много болтают о Progressive Enhancement — PE, но на самом деле почти все аргументы с обеих сторон упускают самую фундаментальную причину, по которой PE..

    Введение в Джанго Фреймворк
    Схема «работать умно, а не усердно» В этой и последующих статьях я познакомлю вас с тем, что такое фреймворк Django и как создать свое первое приложение с помощью простых и понятных шагов, а..