2009-09-13 8 views
15

Ciltleme işlevlerini kullanmayı öğrenmek istiyorum. Ben parametrelere alır bu işlevi var :bind1st ve bind2nd nasıl kullanılır?

void print_i(int t, std::string separator) 
{ 
     std::cout << t << separator; 
} 

Ve yapmak istiyorum:

std::vector<int> elements; 
// ... 
for_each(elements.begin(), elements.end(), std::bind2nd(print_i, '\n')); 

Ama çalışmıyor İşte fikir! İşte

ne alıyorum:

/usr/include/c++/4.3/backward/binders.h: In instantiation of ‘std::binder2nd<void()(int, std::string)>’: 
main.cpp:72: instantiated from here 
/usr/include/c++/4.3/backward/binders.h:138: error: ‘void()(int, std::string)’ is not a class, struct, or union type 
/usr/include/c++/4.3/backward/binders.h:141: error: ‘void()(int, std::string)’ is not a class, struct, or union type 
/usr/include/c++/4.3/backward/binders.h:145: error: ‘void()(int, std::string)’ is not a class, struct, or union type 
/usr/include/c++/4.3/backward/binders.h:149: error: ‘void()(int, std::string)’ is not a class, struct, or union type 
/usr/include/c++/4.3/backward/binders.h:155: error: ‘void()(int, std::string)’ is not a class, struct, or union type 
/usr/include/c++/4.3/backward/binders.h:140: error: field ‘std::binder2nd<void()(int, std::string)>::op’ invalidly declared function type 
/usr/include/c++/4.3/backward/binders.h: In function ‘std::binder2nd<_Operation> std::bind2nd(const _Operation&, const _Tp&) [with _Operation = void()(int, std::string), _Tp = char]’: 
main.cpp:72: instantiated from here 
/usr/include/c++/4.3/backward/binders.h:164: error: ‘void()(int, std::string)’ is not a class, struct, or union type 
/usr/include/c++/4.3/bits/stl_algo.h: In function ‘_Funct std::for_each(_IIter, _IIter, _Funct) [with _IIter = __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, _Funct = std::binder2nd<void()(int, std::string)>]’: 
main.cpp:72: instantiated from here 
/usr/include/c++/4.3/bits/stl_algo.h:3791: error: no match for call to ‘(std::binder2nd<void()(int, std::string)>) (int&)’ 
make: *** [all] Error 1 

Ben functor kullanabilirsiniz, ancak bağlayıcı kullanmak daha hızlıdır.

Teşekkürler!

+2

Bu soruyla ilgili değil, bunun yerine küçük bir yorum. Bir menzil çıkışı için en kısa kod, muhtemelen 'ostream_iterator' biçiminde kopyalanır, örn. std :: copy (v.begin(), v.end(), std :: ostream_iterator (std :: cout, "\ n")). –

cevap

11

bind2nd numaralı argüman AdaptableBinaryFunction olmalıdır. Düz ikili bir işlev bu gereksinimi karşılamaz (dönüş ve bağımsız değişken türleri için yazım kuralları gerekli olan uyarlanabilir bir işlev, düz bir işlev türü herhangi bir yazım hatası sağlamamaktadır). Muhtemelen daha iyi bir seçim olan std::bind'u kullanabilirsiniz.

+0

Lütfen bana bir AdaptableBinaryFunction örneği verebilir misiniz?
Teşekkürler – Arthur

+8

'std :: ptr_fun',' AdaptableBinaryFunction' işlevine ikili işlevi dönüştürebilir: http://www.sgi.com/tech/stl/ptr_fun.html –

25

Bir Kopyalanabilme/Refrencable nesne, aşağıdaki eserlerini kullanmak gerekir: Ayrıca erişime sahip varsayarak

 
#include <iostream> 
#include <vector> 
#include <algorithm> 
#include <iterator> 

int main() 
{ 
    std::vector<int> elements; 
    std::copy(elements.begin(), 
      elements.end(), 
      std::ostream_iterator<int>(std::cout,"\n")); 
    return 0; 
} 

: Normalde sadece aşağıdakileri yaparak aynı etkiyi elde edebilirsiniz

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

void print_i(int t, std::string separator) 
{ 
    std::cout << t << separator; 
} 

int main() 
{ 
    std::vector<int> elements; 
    std::string delim = "\n"; 
    for_each(elements.begin(), 
      elements.end(), 
      std::bind2nd(std::ptr_fun(&print_i),delim)); 
    return 0; 
} 

Kullanmakta olduğunuz STL'deki TR1'e, her zaman en iyi bind1st ve bind2nd ile bd2bbind ile herhangi bir kullanımının değiştirilmesi için en iyi olan:

3

Aşağıdaki adımları uygulamanız gerekir:
1. std :: binary_function
'dan miras alan bir yapı (veya sınıf) oluşturun 2. adım işlevinizi, adım 1
3'te oluşturulan yapının operator() üye işlevinde tanımlayın. Uygun bir şekilde bağlamak için bind2nd öğesini kullanın. 1. adımda oluşturulan yapıya değer

Tüm bunları örnek olarak yaptım. Makaleyi okuyabilir ve aşağıdaki kodun tam kodunu indirebilirsiniz: bind and find

+2

SO'ya hoş geldiniz! kod eklemek için tereddüt etmeyin, düzenleme modunda bir seçenek var düğmesi şöyle görünüyor: '{}', ve kısa bir açıklayıcı kod örneği olması her zaman iyidir, örneğin A sınıfı (public: bool operatörü() (const B & b) {doSomething(); true;} '... sadece bir örnek :-) –