2011-11-16 168 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請求)。 –