C ++, не может скопировать 2 вектора в вектор пары - PullRequest
0 голосов
/ 20 января 2012

Есть следующие типы данных:

struct Item { double a, b; Item (double a_, double b_): a(a_), b(b_){}};
typedef std::pair <double, Item> TPair;
typedef std::vector <TPair> TData;

Я хочу скопировать 2 вектора в вектор пар:

int main(int argc, char* argv[])
{
    std::vector <double> t1;
    std::vector <Item> t2;

    TData data;

    //Error
    std::transform (t1.begin(), t1.end(), data.begin(), 
            std::bind2nd( std::ptr_fun( std::make_pair <double,Item > ), double() ) );
}

Но компилятор останавливается со следующей ошибкой:

Error   1   error C2784: 'std::pointer_to_binary_function<_Arg1,_Arg2,_Result,_Result(__fastcall *)(_Arg1,_Arg2)> 
std::ptr_fun(_Result (__fastcall *)(_Arg1,_Arg2))' : could not deduce template argument for 'overloaded function type' from 'overloaded function type'
Error   2   error C2784: 'std::pointer_to_binary_function<_Arg1,_Arg2,_Result,_Result(__fastcall *)(_Arg1,_Arg2)> 
std::ptr_fun(_Result (__fastcall *)(_Arg1,_Arg2))' : could not deduce template argument for 'overloaded function type' from 'overloaded function type'

В чем проблема?Спасибо за вашу помощь.Компилятор MSVS 2010 x86.Я предпочитаю решение без Boost.

Обновленный вопрос dasblinkenlight обнаружил ошибку, исправленный код:

std::transform (t1.begin(), t1.end(), data.begin(), std::bind1st( std::ptr_fun( std::make_pair <double,Item > ), double() ) );

Но компилятор показывает ту же ошибку ...

Ответы [ 3 ]

1 голос
/ 20 января 2012

Второй аргумент make_pair<double,Item> это Item, а не double:

std::transform (t1.begin(), t1.end(), data.begin(),
     std::bind2nd( std::ptr_fun( std::make_pair <double,Item > ), Item(0,0) ) );

РЕДАКТИРОВАТЬ: Для MS VS я определил make_pair следующим образом:

std::pair<double,Item> make_pair(const double db, const Item it) {
    return std::pair<double,Item>(db, it);
}

Тогда вызов выглядит так:

std::transform (t1.begin(), t1.end(), data.begin(),
     std::bind2nd( std::ptr_fun<double,Item,std::pair<double,Item> >( make_pair), Item(0,0) ) );
1 голос
/ 20 января 2012

Вы не должны использовать устаревшие связыватели, поскольку они будут проходить вас всего за несколько метров, прежде чем вы столкнетесь с чем-то, что в принципе невозможно решить (функция-член с более чем одним аргументом, более чем 2 аргументами, неизвестными типами возврата)и они несовместимы с лямбдами C ++ 11.Для некоторой степени прямой совместимости используйте boost::bind.Ваш код фактически становится:

boost::bind(make_pair<double, Item>, double(), _1);

Квалификация make_pair с аргументами шаблона также будет необходима с std::bind1st (bind1st, потому что вы привязываете аргумент к неправильной позиции, как указывали другие`).

В качестве дополнительного бонуса решение C ++ 03:

std::bind1st(std::ptr_fun(std::make_pair<int, Item>), int());

, которое, как ни странно, не компилируется с C ++ 11 в 4.6.2.Я еще не понял, почему.Но возьмите это в качестве хорошего примера, почему вы не должны использовать устаревшие связующие!

1 голос
/ 20 января 2012

Второй параметр std::make_pair<double,Item> - это Item, а не double. Я думаю, вы хотите использовать std::bind1st вместо.

...