boost :: bind не работает с boost :: tuple :: get <N>() - PullRequest
4 голосов
/ 23 августа 2011

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

      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 )
                     )
            );

Ответы [ 2 ]

8 голосов
/ 23 августа 2011

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

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

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

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

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

// 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 не очень хорошо ладят ...

1 голос
/ 23 августа 2011

Несколько проблем здесь: 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 )

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

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 )
             )
    );
}
...