2011-08-23 1 views
4

Я пытаюсь использовать boost::bind и STL с boost::tuple, но каждый раз, когда я пытаюсь скомпилировать, я получаю следующую ошибку.boost :: bind не работает с boost :: tuple :: get <N>()

 error: call of overloaded ‘bind(<unresolved overloaded function type>, 
     boost::arg<1>&)’ is ambiguous 

Вы знаете, что я делаю неправильно здесь и почему только для boost::arg<1>?

Благодаря AFG

#include <iostream> 
    #include <algorithm> 
    #include <vector> 
    #include <cstdio> 
    #include <boost/tuple/tuple.hpp> 
    #include <boost/assign.hpp> 
    #include <boost/bind.hpp> 

    int main(int argc, const char** argv){ 


      using namespace boost::assign; 
      typedef boost::tuple< int, double > eth_array; 

      std::vector<eth_array> v; 
      v+= boost::make_tuple(10,23.4), boost::make_tuple(12,24.4)); 
      std::for_each(v.begin() 
        , v.end() 
        , boost::bind<int>(
          printf 
          , "%d-%f" 
          , boost::bind(eth_array::get<0>, _1) 
          , boost::bind(eth_array::get<1>, _1) 
        ) 
      ); 
+1

Что такое 'eth_array'? Разве '' '' '' '' 'в' boost' пространство имен? Не это 'names_array' пространство имен/класс? –

+0

auch .. Я изменил код при копировании. Исправлено в примере выше. –

ответ

8

Функция get имеет более одного параметра шаблона: в дополнение к индексу она также параметризуется по содержимому кортежа (голова и хвост cons).

Следовательно, get<0> не является экземпляром шаблона; вам необходимо предоставить дополнительные аргументы:

typedef eth_array::head_type head; 
typedef eth_array::tail_type tail; 

... get<0, head, tail> ... 

Однако, это еще не будет работать, потому что get перегружена (сопзИ и неконстантные версии), поэтому вам нужно явно указать, какие перегружать вы хотите. Для этого вам нужно использовать указатель на функцию с правильным типом:

// const version of get, which takes and returns const references 
int const & (*get0)(boost::tuples::cons<head, tail> const &) = 
    boost::get<0, head, tail>; 
double const & (*get1)(boost::tuples::cons<head, tail> const &) = 
    boost::get<1, head, tail>; 

Теперь вы можете использовать эти указатели на функции в вашем выражении связывания:

std::for_each(v.begin(), 
       v.end(), 
       boost::bind<int>(
        printf, 
        "%d-%f", 
        boost::bind(get0, _1), 
        boost::bind(get1, _1) 
       ) 
); 
// outputs 10-23.40000012-24.400000 

Как вы можете видеть, перегруженные шаблоны функций и bind не очень хорошо ладят ...

+0

Привет, Люк!Это супер-ответ. Никогда не получал так много информации о boost :: tuple + template! –

1

Несколько проблем здесь: eth_array не определен, я предполагаю, что должно быть _array.

v+= (boost::make_tuple(10,23.4))(boost::make_tuple(12,24.4)); 

Здесь вы пытаетесь назвать кортеж как функцию? Может быть, вы пытались что-то вроде:

v+=boost::make_tuple(10,23.4); 
v+=boost::make_tuple(12,24.4); 

Наконец, то, что, кажется, вызывает проблему вы описали:

boost::bind(eth_array::get<0>, _1) 

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

boost::bind(&eth_array::get<0>, _1) 

Полный комплект основного(), который я должен скомпилировать и запустить:

int main(int argc, const char** argv){ 

    using namespace boost::assign; 
    typedef boost::tuple< int, double > _array; 

    std::vector<_array> v; 
    v+=boost::make_tuple(10,23.4); 
    v+=boost::make_tuple(12,24.4); 
    std::for_each(v.begin() 
      , v.end() 
      , boost::bind<int>(
        printf 
        , "%d-%f\n" 
        , boost::bind(&_array::get<0>, _1) 
        , boost::bind(&_array::get<1>, _1) 
      ) 
    ); 
} 
+0

Hi AndrzejJ. Вы правы, я имел в виду v + = boost :: make_tuple (10,23.4), boost :: make_tuple (12,24.4); (Я немного потрудился, и я исправил свой код, чтобы сделать его более читаемым). Дело в том, что boost :: bind (& eth_array :: get <0>, _1) все еще не работает в std :: for_each, даже используя &. Все еще только для arg <1> –

+0

у вас нет типа eth_array, определенного в вашем коде, но когда я использовал _array, я получил его для компиляции и запуска. Я отредактировал свой ответ, чтобы включить всю функцию main(), которая компилируется в моей системе. – AndrzejJ