2013-02-06 24 views
12

Gömülü bir sistem üzerinde çalışıyorum, bu yüzden kod boyutu bir sorundur. Standart kütüphaneyi kullanmak, ikili boyutumu 40k'dan 100k'a kadar 60k civarı artırıyor. Std :: function kullanmak istiyorum ama 60k için bunu haklı çıkaramıyorum. Kullanabileceğim tek bir uygulama var mı, benzer mi? C++ 11.std :: function'un bağımsız bir uygulaması var mı?

+1

Eğer destek denedi fonksiyonu ve artırmak :: bağlama: Eğer (vs hareket gibi ileri/boş çağrı yanıtını) dilediğiniz gibi davranışını özelleştirebilirsiniz? – juanchopanza

+0

@juanchopanza: wrt 'std :: function' kod boyutunu küçültmesi gerekiyor mu? –

+0

Farklı bir C++ kütüphanesi kullanmayı düşündünüz mü, ör. Dinkumware? – nneonneo

cevap

9

İçindeki değişkenlerle üye işlevlerinde örtülü olarak lambdalar kullanıyorum. 60k, std :: function için istisnalar gerektiğinden, derleyici tarafından istisna işleme eklenmiştir. std :: işlevi yalnızca bir istisna atar, "bad_function_call". Bu yüzden istisna attı kod kaldırıldı, şimdi boş bir işlev çağrıldığında arızaları parçalamak ve kendimi 60k kaydettim.

+9

Derleyiciniz muhtemelen 'throw' ifadelerini 'std :: terminate()' (veya onun bazı türevleri) çağrılarına çevirme seçeneğine sahiptir. Dirsek gresi için – GManNickG

+1

+1. Beni güldürdü. – Potatoswatter

+0

Sadece karşılaştırmak için. Şimdi toplam ikili büyüklük nedir? –

8

Herhangi bir başlık eklenmeden std :: işlev benzeri sınıf şablonunun basit uygulaması. ::

live_demo

// Scroll down for example of usage 
namespace bicycle 
{ 
    template<typename Result,typename ...Args> 
    struct abstract_function 
    { 
     virtual Result operator()(Args... args)=0; 
     virtual abstract_function *clone() const =0; 
     virtual ~abstract_function() = default; 
    }; 

    template<typename Func,typename Result,typename ...Args> 
    class concrete_function: public abstract_function<Result,Args...> 
    { 
     Func f; 
    public: 
     concrete_function(const Func &x) 
      : f(x) 
     {} 
     Result operator()(Args... args) override 
     { 
      return f(args...); 
     } 
     concrete_function *clone() const override 
     { 
      return new concrete_function{f}; 
     } 
    }; 

    template<typename Func> 
    struct func_filter 
    { 
     typedef Func type; 
    }; 
    template<typename Result,typename ...Args> 
    struct func_filter<Result(Args...)> 
    { 
     typedef Result (*type)(Args...); 
    }; 

    template<typename signature> 
    class function; 

    template<typename Result,typename ...Args> 
    class function<Result(Args...)> 
    { 
     abstract_function<Result,Args...> *f; 
    public: 
     function() 
      : f(nullptr) 
     {} 
     template<typename Func> function(const Func &x) 
      : f(new concrete_function<typename func_filter<Func>::type,Result,Args...>(x)) 
     {} 
     function(const function &rhs) 
      : f(rhs.f ? rhs.f->clone() : nullptr) 
     {} 
     function &operator=(const function &rhs) 
     { 
      if((&rhs != this) && (rhs.f)) 
      { 
       auto *temp = rhs.f->clone(); 
       delete f; 
       f = temp; 
      } 
      return *this; 
     } 
     template<typename Func> function &operator=(const Func &x) 
     { 
      auto *temp = new concrete_function<typename func_filter<Func>::type,Result,Args...>(x); 
      delete f; 
      f = temp; 
      return *this; 
     } 
     Result operator()(Args... args) 
     { 
      if(f) 
       return (*f)(args...); 
      else 
       return Result{}; 
     } 
     ~function() 
     { 
      delete f; 
     } 
    }; 
} 

// ___________________[ Example of usage ]___________________ // 

int func1(double) 
{ 
    return 1; 
} 
struct Functor2 
{ 
    int operator()(double) 
    { 
     return 2; 
    } 
}; 

double func3(bool,int) 
{ 
    return 3.0; 
} 
struct Functor4 
{ 
    double operator()(bool,int) 
    { 
     return 4.0; 
    } 
}; 

int main() 
{ 
    int res = 10; 
    { 
     bicycle::function<int(double)> f{func1}; 

     res -= f(1.0); 
     f = Functor2{}; 
     res -= f(2.0); 
    } 
    { 
     bicycle::function<double(bool,int)> f1; 
     f1 = func3; 

     bicycle::function<double(bool,int)> f2{f1}; 
     res -= f2(true,1); 

     f1 = Functor4{}; 
     f2 = f1; 
     res -= f2(false,2); 
    } 
    return res; 
} 
+0

Privet Evgeny, inanılmaz bir uygulama, ama nasıl çalışıyor? Neden işlev bir genel ile tanımlanır ve sonra 2 parametreden sonra yeniden tanımlanır. , sessizce böyle bir kodu nasıl yazacağım ilkelerini alamıyorum :) – barney

İlgili konular