Soru Std :: bind ne zaman kullanmalıyım?


Her zaman kullanmam gerek std::bindBen bunun yerine bir lambda kullanarak bitirdim. Ne zaman kullanmalıyım std::bind? Sadece bir kod tabanından çıkarmayı bitirdim ve lambdaların her zaman daha basit ve net olduğunu gördüm. std::bind. değil std::bind tamamen gereksiz mi? Gelecekte kullanımdan kaldırılmamalıdır? Ne zaman tercih etmeliyim std::bind lambda işlevlerine (Lambdas ile aynı zamanda standarda girmesinin bir nedeni olmalı.)

Ayrıca daha fazla insanın lambdalarla tanıştığını fark ettim (böylece lambdaların ne yaptığını biliyorlar). Bununla birlikte, çok daha az insan aşina std::bind ve std::placeholders.


32
2018-03-24 12:44


Menşei


olası kopyası Bind Vs Lambda? - Jonathan Wakely
Bkz. Stackoverflow.com/a/17545183/1274850 - BertR


Cevaplar:


İşte bir lambda ile yapamayacağınız bir şey var:

std::unique_ptr<SomeType> ptr = ...;
return std::bind(&SomeType::Function, std::move(ptr), _1, _2);

Lambdas sadece hareket tarzlarını yakalayamaz; değerleri sadece kopya veya lvalue referansıyla yakalayabilirler. Kuşkusuz bu, C ++ 14 için aktif olarak çözüme kavuşturulan geçici bir sorundur;)

"Daha basit ve daha net" bir fikir meselesidir. Basit ciltleme kılıfları için bind çok daha az yazarak alabilir. bind ayrıca sadece işlev bağlamaya odaklanır, yani görürseniz std::bindNe baktığını biliyorsun. Eğer bir lambda kullanırsanız, lambda uygulamasına, ne yaptığından emin olmak için bakmak zorundasınız.

Son olarak, C ++, bazı başka özelliklerin yaptığı şeyi yapabildiğinden, bazı şeyleri reddetmez. auto_ptr kullanımdan kaldırıldı doğal olarak tehlikeli Kullanmak ve tehlikeli olmayan bir alternatif var.


29
2018-03-24 12:57



+1. İçinde bir öğe var gibi görünüyor Scott Meyers'ın yaklaşan kitabı "Etkin C ++ 11": "Lambdas'ı tercih et std::bind“Bunun hakkında yorum yapmak için yeterli bilgiye sahip değilim, ama eğer yapabilirseniz, bu harika olurdu. - Andy Prowl
Böyle harika bir cevap için teşekkürler! Taşımayla ilgili bir makale var: marcoarena.wordpress.com/2012/11/01/... Umarım bir sonraki standartta hareket ederek gerçek yakalamayı elde ederiz. - gnzlbg
C ++ - 14, bu lambda eksikliğini giderecek. - David Schwartz
@AndyProwl en geçerli, alıntı yaptığınız kitaptaki şu kısa alıntıdır: "... C ++ 14'ten itibaren, [std :: bind] için iyi bir kullanım örneği yoktur" - Drew Dormann
Ben düşünürken, c ++ 14 ile muhtemelen std :: yerine tamamen lambdas ile bağlanabilirsiniz (ve ben çoğunlukla yaparım). std::bind Daha az güçlü olmak ve böylece niyetini daha açık bir şekilde ifade etmek. - MikeMB


İle polimorfik nesneler oluşturabilirsiniz std::bind lambdas ile yapamayacağınız, yani std::bind farklı argüman türleri ile çağrılabilir:

#include <functional>
#include <string>
#include <iostream>

struct Polly
{
  template<typename T, typename U>
    auto operator()(T t, U u) const -> decltype(t + u)
    { return t + u; }
};

int main()
{
  auto polly = std::bind(Polly(), std::placeholders::_1, "confusing");

  std::cout << polly(4) << polly(std::string(" this is ")) << std::endl;    
}

Bunu bir bulmaca iyi bir kod örneği değil, ancak polimorfik çağrı sarmalayıcılarını gösterir.


23
2018-03-24 13:45



c ++ 14 jenerik lambda bu sorunu çözdü mü? - benlong
Evet, C ++ 14'te bu, bağlama ifadesine eşdeğerdir: [p = Polly{}](auto t) { return p(t, "confusing"); } - Jonathan Wakely