简体   繁体   中英

C++, can not copy 2 vectors to vector of pair

There the following data types:

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;

I want to copy 2 vectors into the vector of pairs:

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

But the compiler stops with the following error:

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'

Where is the problem? Thanks for your help. Compiler MSVS 2010 x86. I prefer a solution without Boost.

Updated question An error has been found by dasblinkenlight, the corrected code:

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

But compiler shows the same error...

The second parameter of std::make_pair<double,Item> is an Item not a double . I guess you want to use std::bind1st instead.

The second argument of make_pair<double,Item> is Item , not double :

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

EDIT: For MS VS, I defined make_pair as follows:

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

Then the invocation looks like this:

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

You should not use the deprecated binders as they are only going to take you a few meters before you bump into something that is basically impossible to solve (member function with more than one argument, more than 2 arguments, unknown return types) and they are incompatible with C++11 lambdas. For some degree of forward compatability use boost::bind . Your code effectively becomes:

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

Qualifying make_pair with template arguments will also be necessary with std::bind1st ( bind1st because you are binding the argument to the wrong position, as others have pointed out`).

As an added bonus the C++03 solution:

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

Which, curiously, does not compile with C++11 on 4.6.2. I haven't figured out why yet. But take it as a good example why you shouldn't use the deprecated binders!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM