2012-04-11 3 views
0

Следующий код даст компилировать ошибку, вызванную линии 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); 
} 

Вопрос заключается в том, какого Protoype из functor2 в строке 17 должно быть?
Если я действительно хочу, чтобы прототип functor2, чтобы быть «повышение :: функцию < пустоту() >, как сделать повышение :: привязки возврата такого типа

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

+0

Попытка наддува :: Функция <аннулируются (Т & Const)> functor2 = повышение :: связывания (& A :: Foo , Arg); – Lou

+0

Это не работает. потому что T уже «void (*)()». –

ответ

3

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

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

Посмотрите What is the return type of boost::bind?

Короче говоря, я бы просто написать

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

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

+0

К сожалению, я не могу включить опцию cpp0x. Этот примерный код выше упрощен и минимизирован из реального кода проекта. Жгут проводов сборки фиксирован и не может использовать новый стандарт. –

0

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

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 bind doc, boost mem_fn doc), это то, что, как я думаю, происходит.

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

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

Смежные вопросы