Giriş
Şu satırı dahil ederiz.
C++11 ile gelen std::bind (kendisi boost::bind ile aynıdır) bizi function pointer karmaşasından kurtarıyor bizi.
Şöyle yaparız
std::bind, partial function'lar için kullanılabilir. Partial Function parametrelerden bazılarının sabit olması anlamına gelir.
Aşağıdaki örnekte elimizde 3 tane parametre alan bir metodumuz var. 2. parametreyi 4 sabit değerine bağlamak için istiyoruz. Geri kalan parametreler için de std::placeholder'lar kullanıyoruz.
Eğer overload edilmiş iki metod varsa, derleyici genelde hata veriyor. Bu durumda derleme hatasını aşmak için iki seçeneğimiz var.
Elimizde şöyle bir sınıf olsun
2. std::bind yerine direkt lambda kullanmak.
Şöyle yapmak bazen std::bind'dan daha kolay olabiliyor.
std::bind return type
std::bind için ilginç bir şekilde return type tanımlanmamış.
std::bind ve value semantics
std::bind normalde value semantics ile çalışır yani yani dışarıdan geçilen parametreleri value type olarak kullanır.
Eğer reference semantics kullanmak istersek std::ref kullanmamız gerekir. std::ref bir std::reference_wrapper nesnesi döner.
Şu satırı dahil ederiz.
#include <functional>
Bind'in nasıl çalıştığını görsel olarak anlamak önemli. std::bind yerine lambda'yı tercih edenler çok. Açıklaması şöylestd::bind came from boost::bind, which was necessary before we had lambdas.function pointer olarak kullanımı
Unfortunately std::bind made it into the standard at the same time as lambdas, so it was immediately almost irrelevant.
C++11 ile gelen std::bind (kendisi boost::bind ile aynıdır) bizi function pointer karmaşasından kurtarıyor bizi.
Şöyle yaparız
int main ( void )
{
D d;
auto f = std::bind( &D::foo, _1);
f(&d, 5);
}
partial function olarak kullanımıstd::bind, partial function'lar için kullanılabilir. Partial Function parametrelerden bazılarının sabit olması anlamına gelir.
Sabitleme işlemi için functor yazmak yerine, std::bind kullanmak çok daha kolay bir çözüm."In computer science, partial application (or partial function application) refers to the process of fixing a number of arguments to a function, producing another function of smaller arity. "
Aşağıdaki örnekte elimizde 3 tane parametre alan bir metodumuz var. 2. parametreyi 4 sabit değerine bağlamak için istiyoruz. Geri kalan parametreler için de std::placeholder'lar kullanıyoruz.
auto g = bind(f, _1, 4, _2);
Bir başka örnek şöylestd::function<void(int)> g = std::bind(f, _1, 0) ;
std::bind ve overloadEğer overload edilmiş iki metod varsa, derleyici genelde hata veriyor. Bu durumda derleme hatasını aşmak için iki seçeneğimiz var.
Elimizde şöyle bir sınıf olsun
class Test{
public:
int work(){
cout << "in work " << endl;
return 0;
}
void work(int x){
//cout << "x = " << x << endl;
cout << "in work..." << endl;
}
};
1. cast yapmak
cast şöyle yapılır. cast için function pointer tanımı yerine auto kullanmak çok daha iyi.Test test;
// only overload resolution required here
auto fp = static_cast<int (Test::*)()>(&Test::work);
// type is now unambiguous and overload resolution is already done
std::function<void()> f = std::bind(fp, &test);
cast kodları çok karışık haller alabiliyor. Okunurluğa dikkat etmek önemli.std::function<void()>f=std::bind(static_cast<int(Test::*)()>(&Test::work), &test);
typdef kullanmak ta okunurluğu artırmıyor.Test test;
typedef int(Test:: *WKPtr)(void);
WKPtr p = &Test::work;
std::function<int()> f = std::bind(p, &test);
f();
2. std::bind yerine direkt lambda kullanmak.
Şöyle yapmak bazen std::bind'dan daha kolay olabiliyor.
auto fp = [&t]() { t.test()};
std::bind return type
std::bind için ilginç bir şekilde return type tanımlanmamış.
template< class F, class... Args >
/*unspecified*/ bind( F&& f, Args&&... args );
std::bind ve value semantics
std::bind normalde value semantics ile çalışır yani yani dışarıdan geçilen parametreleri value type olarak kullanır.
int f(double x);
auto fun = std::bind(f, 1.0); // stores a copy, not a reference to a temporary
fun();
std::bind ve reference semanticsEğer reference semantics kullanmak istersek std::ref kullanmamız gerekir. std::ref bir std::reference_wrapper nesnesi döner.
double t=1.0;
auto fun = std::bind(f, std::ref(t));
Eğer ref olamıyorsa derleme hatası alırız.struct A
{
A() = default;
A(const A&) = delete;
A& operator =(const A&) = delete;
void foo() const
{}
};
int main()
{
A a;
std::bind(&A::foo, &a); // ok
std::bind(&A::foo, a); // error
return 0;
}
Hiç yorum yok:
Yorum Gönder