2011-11-16 84 views
3

我想使用std::make_pair可用于例如。 std::bind2nd,这样我就可以得到一个一元函数对象,我可以使用它。 std::transform如何使std :: make_pair与std :: bind *一起使用?

现在,我使用

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总是在保存帖子时将我的标签重写为 ...)。

+1

C++ 0x是C++ 11的工作名称,直到它在几个月前完成。 –

+0

@Mike:啊,说得通。我不知何故认为'C++ 0x'标签也应该符合我的C++ 03问题:-) –

回答

4

你需要std::ptr_fun,它变成一个普通的函数指针为适应二元函数对象(或一元函数对象,如果你传递一个带参数的函数):

#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)); 
+0

你确定这在C++ 11中是合法的吗?在为'make_pair'指定显式模板参数时存在一些问题(例如[see here](http://social.msdn.microsoft.com/Forums/en-US/vclanguage/thread/bab04536-8a8d-4b5e-9a49- e10144688667#b840d54d-d4e9-4602-9273-4118addb8041)和[这里](http://connect.microsoft.com/VisualStudio/feedback/details/465859/make-pair-generates-c2264)和[here](http: //connect.microsoft.com/VisualStudio/feedback/details/691756/std-make-pair-error-in-vc11))... –

+1

@Kerrek:提问者问一个C++ 03解决方案,所以我不知道不确定 :-)。我想对于C++ 11,你可以使用一个包装器'template std :: pair backward_compatible_make_pair(T t,U u)return std :: make_pair(t,u); ''或类似的东西。我认为这应该像旧的C++ 03'make_pair'一样。因此,即使在C++ 11'make_pair'会移动它的情况下,它也会复制该参数。 –

+0

+1啊,完美。我很快就会接受这个答案,以防没有人提出更好的讨论'std :: ptr_fun',这显然正是我想要的。 –

-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); 
    } 
+0

尽管Lambda函数在C++ 03中不可用(由OP请求)。 –

相关问题