如何使用std :: bind *使std :: make_pair可用?

时间:2011-11-16 13:03:51

标签: c++ templates

我想使用std::make_pair可用于例如std::bind2nd以便我得到一个我可以使用的一元函数对象,例如std::transform

现在我正在使用

template <typename T, typename U>
struct pair_creator : std::binary_function<T, U, std::pair<T, U> >
{
    std::pair<T, U> operator()( T arg1, U arg2 ) const {
        return std::make_pair( arg1, arg2 );
    }
};

// ...

std::transform( start1, end2, start2, std::bind2nd( pair_creator<int, bool>(), true ) );

但我想知道 - 是否有一种更简单的方法可以使std::make_pair(或可能是任何其他二进制函数)可用于绑定器,除非通过手工编写像pair_creator这样的小包装类?

我需要一个C ++ 03解决方案(出于某些不明原因,stackoverflow在保存帖子时始终会将标记重写为

2 个答案:

答案 0 :(得分:4)

你需要std::ptr_fun,它将一个普通的函数指针变成一个可适应的二进制函数对象(或者一个函数对象,如果你传递一个arg函数):

#include <functional>
#include <utility>
#include <vector>
#include <algorithm>
#include <iostream>

int main() {
    std::vector<int> intvec;
    intvec.push_back(0);
    intvec.push_back(1);
    std::vector<std::pair<int,bool> > pairvec(intvec.size());
    std::transform(
        intvec.begin(),
        intvec.end(),
        pairvec.begin(),
        // this is the significant line
        std::bind2nd(std::ptr_fun(std::make_pair<int, bool>), true)
    );
    std::cout << pairvec[1].first << " " << pairvec[1].second << "\n";
}
宣布

ptr_fun

template <class Arg1, class Arg2, class Result>
pointer_to_binary_function<Arg1,Arg2,Result>
ptr_fun(Result (*)(Arg1,Arg2));

对于一元版本:

template <class Arg, class Result>
pointer_to_unary_function<Arg,Result>
ptr_fun(Result (*)(Arg));

答案 1 :(得分:-1)

使用lambda不需要使用绑定适配器。

    std::vector<int> start1 = list_of(1)(2)(3)(4)(5);
    std::vector<int> start2 = list_of(10)(20)(30)(40)(50);
    std::vector<Pair> w_vecofpair; // vector of pair
    w_vofpair.reserve(start1.size()); 
    // create pair using lambda
    std::transform( std::begin(start1), std::end(start1), std::begin(start2), // ranges 
        std::back_inserter(w_vecofpair),  // result 
        [](int a,int b) { return std::make_pair(a,b);}); // pair creator

    for (auto& pairInt : w_vecofpair)
    {
        std::cout << pairInt << "\n"; 
    }

    // bind 2nd arg to some value, say 2
    std::transform( std::begin(start1), std::end(start1), std::begin(start2), 
        std::back_inserter(w_vecofpair), [](int a, int b) { return std::make_pair(a,2);});

    for (auto& second : w_vecofpair | map_values)
    {
        std::cout << "The second value of our bind 2nd is: " << second << "\n";
        assert(second==2);
    }