SORU
23 HAZİRAN 2011, PERŞEMBE


Neden fonksiyonları üzerinde funktorlar kullanmak?

Karşılaştırın

double average = CalculateAverage(values.begin(), values.end());

ile

double average = std::for_each(values.begin(), values.end(), CalculateAverage());

Bir işlev içinde bir functor kullanmanın yararları nelerdir? İlk okumayı daha kolay uygulanması eklenir ve daha önce) değil mi?

Eşleme bu gibi tanımlanmış olduğunu varsayalım:

class CalculateAverage
{
private:
   std::size_t num;
   double sum;
public:

   CalculateAverage() : num (0) , sum (0)
   {
   }

   void operator () (double elem) 
   {
      num  ; 
      sum  = elem;
   }

   operator double() const
   {
       return sum / num;
   }
};

CEVAP
23 HAZİRAN 2011, PERŞEMBE


En az dört iyi neden:

Endişeleri ayrılması

Belirli bir örnekte, functor tabanlı bir yaklaşım ortalama hesaplama mantığından yineleme mantığı ayıran bir avantaja sahiptir. Diğer durumlarda, senin functor kullanabilirsiniz (STL diğer tüm algoritmalar düşün) ve for_each diğer funktorlar kullanabilirsiniz.

Parametre oluşturabilme

Bir functor daha kolay parameterise. Bu yüzden, örneğin, kareler, ya da küpler, vb ortalamasını alır CalculateAverageOfPowers bir functor olabilir. böylece yazılı olan verilerinizi,:

class CalculateAverageOfPowers
{
public:
    CalculateAverageOfPowers(float p) : acc(0), n(0), p(p) {}
    void operator() (float x) { acc  = pow(x, p); n  ; }
    float getAverage() const { return acc / n; }
private:
    float acc;
    int   n;
    float p;
};

CalculateAverage farklı bir prototip olduğundan elbette geleneksel bir fonksiyonu ile de aynı şeyi yapabilirsin, ama o zaman zor işlev işaretçileri ile kullanmak için yapar.

Statefulness

Ve funktorlar durum olabilir gibi, böyle bir şey yapabilirsin:

CalculateAverage avg;
avg = std::for_each(dataA.begin(), dataA.end(), avg);
avg = std::for_each(dataB.begin(), dataB.end(), avg);
avg = std::for_each(dataC.begin(), dataC.end(), avg);

ortalama veri setleri farklı. bir takım karşısında

Neredeyse tüm STL funktorlar kabul/konteyner olmalarını gerektirir algoritmaları unutmayın"", yani koşullarına zamanla devlet içinde hiçbir gözlenebilir değişiklik var. saf for_each Bu konuda özel bir durum (örneğin Effective Standard C Library - for_each vs. transform).

Performans

Funktorlar genellikle derleyici (STL şablon bir grup, tüm sonra) tarafından inlined olabilir. Aynı fonksiyonları teorik olarak doğru iken, Compiler genellikle bir işlev işaretçisi aracılığıyla ınline olmaz. Canoncial örnek std::sort Galatasaray qsort; genellikle 5-10 x STL sürümü daha hızlı, basit bir karşılaştırma kendisi yüklem varsayarak karşılaştırın.

Özet

Tabii ki, mümkün olan ilk üç taklit geleneksel işlevleri ve işaretçileri ile, ama funktorlar ile büyük bir anlaşma daha kolay olur.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Break

    Break

    10 Aralık 2005
  • HBO

    HBO

    17 Mayıs 2006
  • Microsoft Research

    Microsoft Re

    24 EKİM 2008