2013-02-06 47 views
12

我正在研究嵌入式系統,所以代碼大小是一個問題。使用標準庫將我的二進制大小從大約60k增加到40k到100k。我想使用std :: function,但是我不能證明它爲60k。是否有可以使用的獨立實現或類似的?我使用它隱式地將成員函數中的lambda轉換爲C++ 11中綁定變量的成員函數。是否有std :: function的獨立實現?

+1

你嘗試過的boost ::功能和boost ::綁定:如你所願(如移動/前進,空呼叫響應等),您可以自定義的行爲? – juanchopanza

+0

@juanchopanza:它是否應該減少代碼的大小「std :: function'? –

+0

您是否考慮過使用其他C++庫,例如Dinkumware的? – nneonneo

回答

9

60k來自編譯器添加的異常處理,因爲std :: function需要異常處理。 std :: function只會引發一個異常,「bad_function_call」。所以我刪除了拋出異常的代碼,現在如果調用一個空函數,它會發生故障,並且我保存了自己60k。

+9

您的編譯器可能有一個選項可將'throw'表達式轉換爲對'std :: terminate()'(或其某些變體)的調用。 – GManNickG

+1

+1用於彎頭油脂。讓我微笑。 – Potatoswatter

+0

只是爲了比較。現在的總二進制大小是多少? –

8

這裏是不包含任何頭文件的std :: function-like類模板的簡單實現。

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,令人驚歎的實現,但它是如何工作的?爲什麼函數是用一個一般的定義的,然後重新定義了2個參數,我悄悄地沒有得到如何編寫這樣的代碼的原則:) – barney