Pracuję nad systemem wbudowanym, więc rozmiar kodu jest problemem. Używanie standardowej biblioteki podnosi mój rozmiar binarny o około 60k, z 40k do 100k. Chciałbym użyć funkcji std ::, ale nie mogę tego uzasadnić dla 60k. Czy istnieje samodzielna implementacja, której mogę użyć lub coś podobnego? Używam go do domyślnego rzucania lambdami w funkcje członkowskie z powiązanymi zmiennymi w języku C++ 11.Czy istnieje samodzielna implementacja funkcji std ::?
Odpowiedz
60k pochodzi z obsługi wyjątków dodawanych przez kompilator, ponieważ wyjątki były wymagane dla funkcji std ::. std :: function rzuca tylko jeden wyjątek, "bad_function_call". Usunąłem więc kod, który wyrzucił wyjątek, teraz usuwa błędy, jeśli wywoływana jest pusta funkcja, a ja zaoszczędziłem sobie 60 tys.
Twój kompilator prawdopodobnie ma opcję zamiany wyrażeń 'throw' na wywołania na' std :: terminate() '(lub jakiś jego wariant). – GManNickG
+1 do smaru do kolan. Wywołał u mnie uśmiech. – Potatoswatter
Tylko do porównania. Jaki jest teraz całkowity rozmiar binarny? –
Oto prosta implementacja szablonu szablonu typu std :: function bez uwzględniania jakichkolwiek nagłówków. Można dostosować zachowanie, jak chcesz (jak przenieść/do przodu, pusty odpowiedź połączeń, etc):
// 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;
}
Privet Evgeny, niesamowita implementacja, ale jak to działa? dlaczego funkcja jest zdefiniowana z jednym ogólnym
próbowałeś boost :: funkcję i boost :: wiążą? – juanchopanza
@juanchopanza: Czy ma zmniejszyć rozmiar kodu wrt 'std :: function'? –
Czy rozważałeś użycie innej biblioteki C++, np. Dinkumware? – nneonneo