2013-02-06 19 views
12

Tôi đang làm việc trên một hệ thống nhúng, do đó kích thước mã là một vấn đề. Sử dụng thư viện chuẩn tăng kích thước nhị phân của tôi lên khoảng 60k, từ 40k đến 100k. Tôi muốn sử dụng std :: function, nhưng tôi không thể biện minh cho nó cho 60k. Có một triển khai độc lập nào mà tôi có thể sử dụng hoặc một cái gì đó tương tự? Tôi đang sử dụng nó để ngầm đúc lambdas trong các hàm thành viên với các biến bị ràng buộc trong C++ 11.Có triển khai std :: function độc lập không?

+1

Bạn đã thử tăng :: chức năng và tăng cường :: ràng buộc? – juanchopanza

+0

@juanchopanza: Nó có phải giảm kích thước mã lệnh 'std :: function' không? –

+0

Bạn đã cân nhắc sử dụng một thư viện C++ khác, ví dụ: Dinkumware? – nneonneo

Trả lời

9

60k đến từ việc xử lý ngoại lệ được trình biên dịch thêm vào, vì ngoại lệ được yêu cầu cho hàm std ::. std :: function chỉ ném một ngoại lệ, "bad_function_call". Vì vậy, tôi loại bỏ mã mà đã ném ngoại lệ, bây giờ nó seg lỗi nếu một chức năng trống được gọi là, và tôi đã lưu bản thân mình 60k.

+9

Trình biên dịch của bạn có thể có tùy chọn để biến các biểu thức 'throw' thành các lệnh gọi thành' std :: terminate() '(hoặc một số biến thể của chúng). – GManNickG

+1

+1 cho mỡ khuỷu tay. Khiến tôi mỉm cười. – Potatoswatter

+0

Chỉ để so sánh. Tổng kích thước nhị phân bây giờ là gì? –

8

Dưới đây là triển khai đơn giản std :: mẫu lớp giống như chức năng mà không bao gồm bất kỳ tiêu đề nào. Bạn có thể tùy chỉnh các hành vi như bạn muốn (như di chuyển/về phía trước, đáp ứng cuộc gọi trống rỗng, vv):

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, thực hiện tuyệt vời, nhưng nó hoạt động như thế nào? tại sao chức năng được định nghĩa với một chung đầu tiên và sau đó redefined lấy 2 tham số , tôi lặng lẽ không hiểu các nguyên tắc viết code như thế :) – barney