I'm porting FastDelegate to C++0x using variadic templates.
#include "FastDelegate.h"
template<class R=fastdelegate::detail::DefaultVoid, class ...P>
class fast_delegate_base {
private:
typedef typename fastdelegate::detail::DefaultVoidToVoid<R>::type desired_ret_t;
typedef desired_ret_t (*static_func_ptr)(P...);
typedef R (*unvoid_static_func_ptr)(P...);
typedef R (fastdelegate::detail::GenericClass::*generic_mem_fn)(P...);
typedef fastdelegate::detail::ClosurePtr<generic_mem_fn, static_func_ptr, unvoid_static_func_ptr> closure_t;
closure_t closure_;
public:
// Typedefs to aid generic programming
typedef fast_delegate_base type;
// Construction and comparison functions
fast_delegate_base() { clear(); }
fast_delegate_base(const fast_delegate_base &x)
{
closure_.CopyFrom(this, x.closure_);
}
void operator = (const fast_delegate_base &x)
{
closure_.CopyFrom(this, x.closure_);
}
bool operator ==(const fast_delegate_base &x) const
{
return closure_.IsEqual(x.closure_);
}
bool operator !=(const fast_delegate_base &x) const
{
return !closure_.IsEqual(x.closure_);
}
bool operator <(const fast_delegate_base &x) const
{
return closure_.IsLess(x.closure_);
}
bool operator >(const fast_delegate_base &x) const
{
return x.closure_.IsLess(closure_);
}
// Binding to non-const member functions
template<class X, class Y>
fast_delegate_base(Y *pthis, desired_ret_t (X::* function_to_bind)(P...) )
{
closure_.bindmemfunc(fastdelegate::detail::implicit_cast<X*>(pthis), function_to_bind);
}
template<class X, class Y>
inline void bind(Y *pthis, desired_ret_t (X::* function_to_bind)(P...))
{
closure_.bindmemfunc(fastdelegate::detail::implicit_cast<X*>(pthis), function_to_bind);
}
// Binding to const member functions.
template<class X, class Y>
fast_delegate_base(const Y *pthis, desired_ret_t (X::* function_to_bind)(P...) const)
{
closure_.bindconstmemfunc(fastdelegate::detail::implicit_cast<const X*>(pthis), function_to_bind);
}
template<class X, class Y>
inline void bind(const Y *pthis, desired_ret_t (X::* function_to_bind)(P...) const)
{
closure_.bindconstmemfunc(fastdelegate::detail::implicit_cast<const X *>(pthis), function_to_bind);
}
// Static functions. We convert them into a member function call.
// This constructor also provides implicit conversion
fast_delegate_base(desired_ret_t (*function_to_bind)(P...) )
{
bind(function_to_bind);
}
// for efficiency, prevent creation of a temporary
void operator = (desired_ret_t (*function_to_bind)(P...) )
{
bind(function_to_bind);
}
inline void bind(desired_ret_t (*function_to_bind)(P...))
{
closure_.bindstaticfunc(this, &fast_delegate_base::invoke_static_func, function_to_bind);
}
// Invoke the delegate
template<typename ...A>
R operator()(A&&... args) const
{
return (closure_.GetClosureThis()->*(closure_.GetClosureMemPtr()))(std::forward<A>(args)...);
}
// Implicit conversion to "bool" using the safe_bool idiom
private:
typedef struct safe_bool_struct
{
int a_data_pointer_to_this_is_0_on_buggy_compilers;
static_func_ptr m_nonzero;
} useless_typedef;
typedef static_func_ptr safe_bool_struct::*unspecified_bool_type;
public:
operator unspecified_bool_type() const { return empty()? 0: &safe_bool_struct::m_nonzero; }
// necessary to allow ==0 to work despite the safe_bool idiom
inline bool operator==(static_func_ptr funcptr) { return closure_.IsEqualToStaticFuncPtr(funcptr); }
inline bool operator!=(static_func_ptr funcptr) { return !closure_.IsEqualToStaticFuncPtr(funcptr); }
// Is it bound to anything?
inline bool operator ! () const { return !closure_; }
inline bool empty() const { return !closure_; }
void clear() { closure_.clear();}
// Conversion to and from the DelegateMemento storage class
const fastdelegate::DelegateMemento & GetMemento() { return closure_; }
void SetMemento(const fastdelegate::DelegateMemento &any) { closure_.CopyFrom(this, any); }
private:
// Invoker for static functions
R invoke_static_func(P... args) const
{
return (*(closure_.GetStaticFunction()))(args...);
}
};
// fast_delegate<> is similar to std::function, but it has comparison operators.
template<typename _Signature>
class fast_delegate;
template<typename R, typename ...P>
class fast_delegate<R(P...)> : public fast_delegate_base<R, P...>
{
public:
typedef fast_delegate_base<R, P...> BaseType;
fast_delegate() : BaseType() { }
template<class X, class Y>
fast_delegate(Y * pthis, R (X::* function_to_bind)(P...))
: BaseType(pthis, function_to_bind)
{ }
template<class X, class Y>
fast_delegate(const Y *pthis, R (X::* function_to_bind)(P...) const)
: BaseType(pthis, function_to_bind)
{ }
fast_delegate(R (*function_to_bind)(P...))
: BaseType(function_to_bind)
{ }
void operator = (const BaseType &x)
{
*static_cast<BaseType*>(this) = x;
}
};
But, one of the limitations of my implementation is, when using non-member functions, and in case that function accepts parameter(s) by value, an extra value copy for each parameters take place. I assume that this occurs between fast_delegate_base::operator()() and fast_delegate_base::invoke_static_func().
I tried to make fast_delegate_base::invoke_static_func() to accept Rvalue parameters, but failed.
For example:
class C1
{
public:
C1() { printf("C1()\n"); }
~C1() { printf("~C1()\n"); }
C1(const C1&)
{
printf("C1(const C1&)\n");
}
int test(int t) const
{
printf("C1::test(%d)\n", t);
return 1;
}
};
int test(C1 c)
{
c.test(1234);
return 1;
}
// ...
C1 c1;
fast_delegate<int(C1)> t1(test);
t1(c1);
Result of this code is:
C1()
C1(const C1&)
C1(const C1&)
C1::test(1234)
~C1()
~C1()
~C1()
Do you have any idea to avoid this extra value copy?
It looks to me like this copy is inherent in the design of the class, specifically the existence of invoke_static_func.
From what I can see, this is a proxy to normalize static functions and member functions into just member functions, so they every dispatch can be done as a member function call. The only difference is that the member is the fast_delegate_base instance rather than an instance of whatever class the target function is a member of.
So there's an extra call frame when calling static functions, and to get rid of that extra copy you would need to make the extra call frame (invoke_static_func) take its parameter by a reference (ignore for now the consequences of this if the argument type is not a value).
Unfortunately, invoke_static_func needs to be called via a function pointer which has an argument list containing value types, so operator() is forced to make a copy in order to invoke the function pointer (i.e. to invoke invoke_static_func). Making invoke_static_func take parameters by reference doesn't help, because it still has to be invoked via a function pointer that does not have reference argument types.
And there's no way invoke_static_func can avoid making a copy to call test(C1), that's just a simple call by value - so you need both copies to make this design work.
To explain it from a different perspective, thin of it in terms of pure C:
Operator() needs to call a function func (this_ptr, arg_1, arg_2, arg_3). The target function will expect these parameters to be in particular registers or particular stack locations depending on their position in the argument list and size.
But a static function does not have the magic first 'this' parameter, its signature is just func(arg_1, arg_2, arg_3). So it expects all the other arguments to be in different registers and/or stack locations than the corresponding member function does. So you need that copy to move the arguments into the right registers/stack locations to comply with the calling convention for the static function.
Which basically, means you can't avoid that second copy for a static function with this design.
However... you may be able to improve on this by some crafty template metaprogramming to apply std::move to value type arguments in the implementation of invoke_static_func, reducing your call overhead to a copy and a move, which is almost as good as just one copy.
I'll update this answer if and when I figure whether that's possible (and if so how).
Edit
Something like this should do the trick:
template <bool IsClass, class U>
struct move_if_class
{
template <typename T>
T&& operator()(const T& t) { return std::move(const_cast<T&>(t)); }
};
template <class T>
struct move_if_class<false,T>
{
T&& operator()(typename std::remove_reference<T>::type& t) { return std::forward<T>(t); }
T&& operator()(typename std::remove_reference<T>::type&& t) { return std::forward<T>(t); }
};
R invoke_static_func(P... args) const
{
return (*(closure_.GetStaticFunction()))(move_if_class<std::is_class<P>::value,P>()(args)...);
}
And after adding a move c'tor:
C1()
C1(const C1&)
C1(C1&&)
C1::test(1234)
~C1()
~C1()
~C1()
Related
I want to define a class, called Nested here, that will contains two or more (one here) data members that support arithmetic operations using expression templates, for example an std::valarray. For this class itself, I am defining its own expression templates and I want to "forward" the arithmetic operations down to the members.
A minimal (non)working example is given below:
#include <iostream>
#include <valarray>
template <typename E>
struct NestedExpr {
operator const E& () const {
return *static_cast<const E*>(this);
}
};
template <typename A>
class Nested : public NestedExpr <Nested<A>>{
private:
A a;
public:
Nested(const A& _a) : a(_a) {}
template <typename E>
inline Nested<A>& operator = (const NestedExpr<E>& _expr) {
const E& expr(_expr);
a = expr.get_a();
return *this;
}
inline A& get_a() { return a; }
inline const A& get_a() const { return a; }
};
// ================================================================= //
template <typename ARG, typename S>
class NestedMul : public NestedExpr<NestedMul<ARG, S>> {
public:
const ARG& arg;
const S s;
NestedMul(const ARG& _arg, S _s) : arg(_arg), s(_s) {}
inline auto get_a() const { return arg.get_a() * s; };
};
template< typename ARG, typename S>
inline NestedMul<ARG, S> operator * (S s, const NestedExpr<ARG>& arg) {
return {arg, s};
}
// ================================================================= //
template <typename ARG1, typename ARG2>
class NestedAdd : public NestedExpr<NestedAdd<ARG1, ARG2>> {
public:
const ARG1& arg1;
const ARG2& arg2;
NestedAdd(const ARG1& _arg1, const ARG2& _arg2)
: arg1(_arg1), arg2(_arg2) {}
inline auto get_a() const { return arg1.get_a() + arg2.get_a(); };
};
template<typename ARG1, typename ARG2>
inline NestedAdd<ARG1, ARG2>
operator + (const NestedExpr<ARG1>& arg1, const NestedExpr<ARG2>& arg2) {
return {arg1, arg2};
}
int main () {
std::valarray<double> x1 = {4.0};
std::valarray<double> x2 = {3.0};
std::valarray<double> x3 = {0.0};
std::valarray<double> x4 = {0.0};
auto a = Nested<std::valarray<double>>(x1);
auto b = Nested<std::valarray<double>>(x2);
auto c = Nested<std::valarray<double>>(x3);
// this returns 21
c = 2*a + 3*b;
std::cout << c.get_a()[0] << std::endl;
// works as expected, returns 17
x4 = 2*x1 + 3*x2;
std::cout << x4[0] << std::endl;
}
The output of this program is
21
17
i.e. forwarding the expression down to the member does not seem to provide the expected result obtained directly from using the valarrays.
Any help here is appreciated.
In the below function definition:
inline auto get_a() const { return arg.get_a() * s; };
your expected behavior is that auto deduces std::valarray<double>, that is, the result type of a multiplication of std::valarray<double> and int which is a new object that already stores values multiplied by the integer.
This is how operator* is defined [valarray.binary]/p2:
template <class T>
valarray<T> operator*(const valarray<T>&,
const typename valarray<T>::value_type&);
However, there's the following paragraph in the standard [valarray.syn]/p3:
Any function returning a valarray<T> is permitted to return an object of another type, provided all the const member functions of valarray<T> are also applicable to this type. This return type shall not add more than two levels of template nesting over the most deeply nested argument type.
This type must be convertible to std::valarray<double>, but itself, for optimization purposes, may not represent the actual result before that conversion happens.
That is, here's the actual type deduced for auto by GCC:
std::_Expr<std::__detail::_BinClos<std::__multiplies
, std::_ValArray
, std::_Constant, double, double>, double>
and here's what Clang uses:
std::__1::__val_expr<std::__1::_BinaryOp<std::__1::multiplies<double>,
std::__1::valarray<double>, std::__1::__scalar_expr<double> > >
In other words, you are returning by value an object which probably defers the actual computations. In order to do so, those intermediate objects need to store somehow the deferred subexpressions.
Inspecting GCC libstdc++'s implementation, one can find the following representation:
template <class _Oper, class _FirstArg, class _SecondArg>
class _BinBase
{
public:
typedef typename _FirstArg::value_type _Vt;
typedef typename __fun<_Oper, _Vt>::result_type value_type;
_BinBase(const _FirstArg& __e1, const _SecondArg& __e2)
: _M_expr1(__e1), _M_expr2(__e2) {}
// [...]
private:
const _FirstArg& _M_expr1;
const _SecondArg& _M_expr2;
};
Note that subexpressions are stored as references. This means that in the definition of get_a():
return arg1.get_a() + arg2.get_a();
_M_expr1 and _M_expr2 are bound to temporary objects:
arg1.get_a()
arg2.get_a()
i.e., intermediate objects which are the results of multiplications, whose lifetime ends as soon as NextedAdd::get_a() exits, leading to undefined behavior when the result is eventually computed, in particular, when the implementation attempts to access each individual element of that intermediate subexpressions:
value_type operator[](size_t __i) const
{
return _Oper()(_M_expr1[__i], _M_expr2[__i]);
}
A quick solution would be to use the following return type:
std::decay_t<decltype(arg.get_a())> get_a() const { return arg.get_a() * s; }
This will recursively ensure that the final result type of any operation will be whatever the original type T in Nested<T> was, i.e., std::valarray<double>.
DEMO
I am working in a memory constrained embedded environment where malloc/free new/delete are not advisable, and I'm trying to use the std::function pattern to register callbacks. I do not have access to any of the STL methods in my target code so I'm in the unfortunate situation of having to replicate some of the STL functionality myself. Function pointers are not an option for me due to the necessity for callers to have captures.
For instance, I wish to declare a class Mailbox where an onChange event can be registered
class Mailbox {
std::function<void(int,int)> onChange;
};
That way, callers can register a lambda onChange handler that could capture this or other variables that matter for handling the event.
Since this is part of an API, I want to give the users of Mailbox maximim flexibility to either provide a function pointer, a lambda or a functor.
I have managed to find a great implementation of a std::function that appears to be exceptionally low-overhead and has exactly what I need except that it involves dynamic memory.
If you look at the following code, dynamic memory is used in exactly one place, and it appears fully scoped to the object being templated, suggesting to me that its size ought to be known at compile-time.
Can anyone help me understand how to refactor this implementation so that it is fully static and removes the use of new/malloc? I'm having trouble understanding why the size of CallableT wouldn't be calculable at compile-time.
Code below (not for the faint of heart). Note, it uses make_unique / unique_ptr but those can easily be substituted with new and * and I have tested that use case successfully.
#include <iostream>
#include <memory>
#include <cassert>
using namespace std;
template <typename T>
class naive_function;
template <typename ReturnValue, typename... Args>
class naive_function<ReturnValue(Args...)> {
public:
template <typename T>
naive_function& operator=(T t) {
callable_ = std::make_unique<CallableT<T>>(t);
return *this;
}
ReturnValue operator()(Args... args) const {
assert(callable_);
return callable_->Invoke(args...);
}
private:
class ICallable {
public:
virtual ~ICallable() = default;
virtual ReturnValue Invoke(Args...) = 0;
};
template <typename T>
class CallableT : public ICallable {
public:
CallableT(const T& t)
: t_(t) {
}
~CallableT() override = default;
ReturnValue Invoke(Args... args) override {
return t_(args...);
}
private:
T t_;
};
std::unique_ptr<ICallable> callable_;
};
void func() {
cout << "func" << endl;
}
struct functor {
void operator()() {
cout << "functor" << endl;
}
};
int main() {
naive_function<void()> f;
f = func;
f();
f = functor();
f();
f = []() { cout << "lambda" << endl; };
f();
}
Edit: added clarification on STL
The name for what you're looking for is "in-place function". At least one very good implementation exists today:
sg14::inplace_function<R(A...), Size, Align>
There is also tj::inplace_any<Size, Align>, if you need/want the semantics of any.
Let me preface this answer by saying that storing a general callable faces an interesting choice in terms of memory management. Yes, we can deduce the size of any callable at compile time but we can not store any callable into the same object without memory management. That's because our own object needs to have size independently of the callables its supposed to store but those can be arbitrarily big.
To put this reasoning into one sentence: The layout of our class (and its interface) needs to be compiled without knowledge about all of the callers.
This leaves us with essentially 3 choices
We embrace memory management. We dynamically copy the callable and properly manage that memory through means of unique pointer (std or boost), or through custom calls to new and delete. This is what the original code you found does and is also done by std::function.
We only allow certain callables. We create some custom storage inside our object to hold some forms of callables. This storage has a pre-determined size and we reject any callable given that can not adhere to this requirement (e.g. by a static_assert). Note that this does not necessarily restrict the set of possible callers. Instead, any user of the interface could set up a proxy-class holding merely a pointer but forwarding the call operator. We could even offer such a proxy class ourselves as part of the library. But this does nothing more than shifting the point of allocation from inside the function implementation to outside. It's still worth a try, and #radosław-cybulski comes closest to this in his answer.
We don't do memory management. We could design our interface in a way that it deliberately refuses to take ownership of the callable given to it. This way, we don't need to to memory management and this part is completely up to our caller. This is what I will give code for below. It is not a drop-in replacement for std::function but the only way I see to have a generic, allocation-free, copiable type for the purpose you inteded it.
And here is the code for possibility 3, completely without allocation and fully self-contained (does not need any library import)
template<typename>
class FunctionReference;
namespace detail {
template<typename T>
static T& forward(T& t) { return t; }
template<typename T>
static T&& forward(T&& t) { return static_cast<T&&>(t); }
template<typename C, typename R, typename... Args>
constexpr auto get_call(R (C::* o)(Args...)) // We take the argument for sfinae
-> typename FunctionReference<R(Args...)>::ptr_t {
return [](void* t, Args... args) { return (static_cast<C*>(t)->operator())(forward<Args>(args)...); };
}
template<typename C, typename R, typename... Args>
constexpr auto get_call(R (C::* o)(Args...) const) // We take the argument for sfinae
-> typename FunctionReference<R(Args...)>::ptr_t {
return [](void* t, Args... args) { return (static_cast<const C*>(t)->operator())(forward<Args>(args)...); };
}
template<typename R, typename... Args>
constexpr auto expand_call(R (*)(Args...))
-> typename FunctionReference<R(Args...)>::ptr_t {
return [](void* t, Args... args) { return (static_cast<R (*)(Args...)>(t))(forward<Args>(args)...); };
}
}
template<typename R, typename... Args>
class FunctionReference<R(Args...)> {
public:
using signature_t = R(Args...);
using ptr_t = R(*)(void*, Args...);
private:
void* self;
ptr_t function;
public:
template<typename C>
FunctionReference(C* c) : // Pointer to embrace that we do not manage this object
self(c),
function(detail::get_call(&C::operator()))
{ }
using rawfn_ptr_t = R (*)(Args...);
FunctionReference(rawfn_ptr_t fnptr) :
self(fnptr),
function(detail::expand_call(fnptr))
{ }
R operator()(Args... args) {
return function(self, detail::forward<Args>(args)...);
}
};
For seeing how this then works in action, go to https://godbolt.org/g/6mKoca
Try this:
template <class A> class naive_function;
template <typename ReturnValue, typename... Args>
class naive_function<ReturnValue(Args...)> {
public:
naive_function() { }
template <typename T>
naive_function(T t) : set_(true) {
assert(sizeof(CallableT<T>) <= sizeof(callable_));
new (_get()) CallableT<T>(t);
}
template <typename T>
naive_function(T *ptr, ReturnValue(T::*t)(Args...)) : set_(true) {
assert(sizeof(CallableT<T>) <= sizeof(callable_));
new (_get()) CallableT<T>(ptr, t);
}
naive_function(const naive_function &c) : set_(c.set_) {
if (c.set_) c._get()->Copy(&callable_);
}
~naive_function() {
if (set_) _get()->~ICallable();
}
naive_function &operator = (const naive_function &c) {
if (this != &c) {
if (set_) _get()->~ICallable();
if (c.set_) {
set_ = true;
c._get()->Copy(&callable_);
}
else
set_ = false;
}
return *this;
}
ReturnValue operator()(Args... args) const {
return _get()->Invoke(args...);
}
ReturnValue operator()(Args... args) {
return _get()->Invoke(args...);
}
private:
class ICallable {
public:
virtual ~ICallable() = default;
virtual ReturnValue Invoke(Args...) = 0;
virtual void Copy(void *dst) const = 0;
};
ICallable *_get() {
return ((ICallable*)&callable_);
}
const ICallable *_get() const { return ((const ICallable*)&callable_); }
template <typename T>
class CallableT : public ICallable {
public:
CallableT(const T& t)
: t_(t) {
}
~CallableT() override = default;
ReturnValue Invoke(Args... args) override {
return t_(std::forward<ARGS>(args)...);
}
void Copy(void *dst) const override {
new (dst) CallableT(*this);
}
private:
T t_;
};
template <typename T>
class CallableT<ReturnValue(T::*)(Args...)> : public ICallable {
public:
CallableT(T *ptr, ReturnValue(T::*)(Args...))
: ptr_(ptr), t_(t) {
}
~CallableT() override = default;
ReturnValue Invoke(Args... args) override {
return (ptr_->*t_)(std::forward<ARGS>(args)...);
}
void Copy(void *dst) const override {
new (dst) CallableT(*this);
}
private:
T *ptr_;
ReturnValue(T::*t_)(Args...);
};
static constexpr size_t size() {
auto f = []()->void {};
return std::max(
sizeof(CallableT<void(*)()>),
std::max(
sizeof(CallableT<decltype(f)>),
sizeof(CallableT<void (CallableT<void(*)()>::*)()>)
)
);
};
typedef unsigned char callable_array[size()];
typename std::aligned_union<0, callable_array, CallableT<void(*)()>, CallableT<void (CallableT<void(*)()>::*)()>>::type callable_;
bool set_ = false;
};
Keep in mind, that sort of tricks tend to be slightly fragile.
In this case to avoid memory allocation i used unsigned char[] array of assumed max size - max of CallableT with pointer to function, pointer to member function and lambda object. Types of pointer to function and member function dont matter, as standard guarantees, that for all types those pointers will have the same size. Lambda should be pointer to object, but if for some reason isnt and it's size will change depending on lambda types, then you're out of luck.
First callable_ is initialized with placement new and correct CallableT type. Then, when you try to call, i use beginning of callable_ as pointer to ICallable. This all is standard safe.
Keep in mind, that you copy naive_function object, it's template argument T's copy operator is NOT called.
UPDATE: some improvements (at least try to force alignment) + addition of copying constructor / copy assignment.
My attempt to run the solution given Here, encountered with some issues. After fixing them, seems to work fine.
Will be happy for any review as I am not a c++ expert!
Issues and fixes:
error: lambda expression in an unevaluated operand.
removed the decltype. ( was not present in original code so I guess its safe(???)
using aligned_t = detail::aligned_union<0,
CallableT<void(*)()>,
//CallableT<decltype([]()->void {})>,
CallableT<void (CallableT<void(*)()>::*)()>
>;
Under C++11, errors in code block:
error: fields must have a constant size: 'variable length array in structure' extension will never be supported
error: 'aligned' attribute requires integer constant
error: constexpr variable 'alignment_value' must be initialized by a constant expression
(Note: this code is replacing std::aligned_union)
namespace detail {
template <size_t Len, class... Types>
struct aligned_union {
static constexpr size_t alignment_value = std::max({alignof(Types)...}); // ERROR HERE C++11
struct type {
alignas(alignment_value) char _s[std::max({Len, sizeof(Types)...})]; // ERROR HERE C++11
};
};
}
Used 'external' help from ETLCPP - which has support for embedded, file: largest.h.
Error block was replaced with :
#include"etl/largest.h"
template<typename ...Types>
using largest_t = typename etl::largest_type<Types...>::type;
namespace detail {
template <size_t Len, class... Types>
struct aligned_union {
static constexpr size_t alignment_value = etl::largest_alignment<Types...>::value; //std::max({alignof(Types)...});
struct type {
alignas(alignment_value) char _s[sizeof(largest_t<Types...>)]; //[std::max({Len, sizeof(Types)...})];
};
};
}
Looked redundant, removed:
//static constexpr size_t size() {
// auto f = []()->void {};
// return std::max(
// sizeof(CallableT<void(*)()>),
// std::max(
// sizeof(CallableT<decltype(f)>),
// sizeof(CallableT<void (CallableT<void(*)()>::*)()>)
// )
// );
//};
replaced std::forward with etl::forward file: utility.h
Had anew ,and delete errors : Undefined symbol operator delete
(void)*
So added ( I never allocate.. ):
// Define placement new if no new header is available
inline void* operator new(size_t, void* p) { return p; }
inline void* operator new[](size_t, void* p) { return p; }
inline void operator delete(void*, void*) {}
inline void operator delete[](void*, void*) {}
inline void operator delete[](void*) {}
Still getting a warning thought (???):
: warning: replacement function 'operator delete' cannot be declared 'inline' [-Winline-new-delete]
inline void operator delete(void* ) {}
Linker error:
Error: L6218E: Undefined symbol __cxa_pure_virtual ).
Probably because of virtual distractor : (ref)
virtual ~ICallable() = default;
Had to add this : ( any other solution ???)
extern "C" void __cxa_pure_virtual() { while (1); }
I have my own Runnable class that can store function pointer, member function (maybe lambda) pointer or functor and run it in one way. Here's reduced version of it:
template<typename returnType, typename... args>
class Runnable
{
private:
template<typename rreturnType, typename... aargs>
struct FuncBase
{
virtual returnType run(aargs...) const = 0;
virtual FuncBase<rreturnType, aargs...>* clone() const = 0;
virtual ~FuncBase() { }
};
template<typename rreturnType, typename... aargs>
struct Func : FuncBase<rreturnType, aargs...>
{
rreturnType (*func) (aargs...);
rreturnType run(aargs... arg) const { return func(arg...); }
FuncBase<rreturnType, aargs...>* clone() const { return new Func<rreturnType, args...>(func); }
Func(rreturnType (*func) (aargs...)) : func(func) { }
};
template<typename memberType, typename rreturnType, typename... aargs>
struct MemberFunc : public FuncBase<rreturnType, aargs...>
{
memberType& owner;
rreturnType (memberType::*member) (args...);
rreturnType run(aargs... arg) const { return (owner.*member)(arg...); }
FuncBase<rreturnType, aargs...>* clone() const { return new MemberFunc<memberType, rreturnType, aargs...>(owner, member); }
MemberFunc(memberType& owner, rreturnType (memberType::*member) (aargs...)) : owner(owner), member(member) { }
};
template<typename functorType, typename rreturnType, typename... aargs>
struct FunctorFunc : public FuncBase<rreturnType, aargs...>
{
functorType& owner;
rreturnType run(aargs... arg) const { return owner(arg...); }
FuncBase<rreturnType, aargs...>* clone() const { return new FunctorFunc<functorType, rreturnType, aargs...>(owner); }
FunctorFunc(functorType& owner) : owner(owner) { }
};
FuncBase<returnType, args...>* f;
Runnable(const Runnable<returnType, args...>& r) = delete;
Runnable<returnType, args...>& operator=(const Runnable<returnType, args...>& r) = delete;
public:
Runnable(returnType (*func) (args...)) { f = new Func<returnType, args...>(func); }
template<typename memberType>
Runnable(memberType& owner, returnType (memberType::*member) (args...)) { f = new MemberFunc<memberType, returnType, args...>(owner, member); }
template<typename functorType>
Runnable(functorType& owner) { f = new FunctorFunc<functorType, returnType, args...>(owner); }
~Runnable() { delete f; }
returnType operator() (args... arg) const { return f->run(arg...); }
};
And I want to store in the same way a mutable lambda function
I can store normal lambda, but when I try to store mutable lambda e.g:
int fk = 20;
Runnable<double, double> r([&](double d) mutable -> double { cout << fk; return d; });
r(1.0);
I get followig error:
no matching function for call to 'Runnable<double, double>::Runnable(main()::__lambda0)'
Runnable<double, double> r([&](double d) mutable -> double { cout << fk; return d; });
When I remove references from Runnable::FunctorFunc
template<typename functorType, typename rreturnType, typename... aargs>
struct FunctorFunc : public FuncBase<rreturnType, aargs...>
{
functorType owner;
rreturnType run(aargs... arg) { return owner(arg...); }
FuncBase<rreturnType, aargs...>* clone() const { return new FunctorFunc<functorType, rreturnType, aargs...>(owner); }
FunctorFunc(functorType owner) : owner(owner) { }
};
It's right in mutable lambdas but I get following error from normal lambdas:
cannot allocate an object of abstract type 'Runnable<double, double>::FunctorFunc<tsf::easing::__lambda0, double, double>'
Runnable(functorType owner) { f = new FunctorFunc<functorType, returnType, args...>(owner); }
^
^
The main issue is how I can modify this class to accept lambdas.
Or maybe someone have similar class or other solution for this problem
The evaluation of a lambda expression results in a prvalue temporary. In your constructor for functor objects
template<typename functorType> Runnable(functorType& owner) { /*...*/ }
you're trying to bind a non-const lvalue reference to such a temporary. This can't work, and it won't work regardless of whether the lambda is mutable or not.
I'm guessing it appeared to work for a non-mutable lambda because you used one that didn't capture anything; such objects are implicitly convertible to function pointers, so that call actually resolved to the constructor taking a function pointer.
You could declare the constructor to take a forwarding reference instead, but you'll have to actually copy or move the argument into the owner member of FunctorFunc. That member cannot be a reference, as it could be dangling once the call to the constructor has finished - the argument is a temporary if it's a lambda expression, remember?
Here's a modified FunctorFunc that does what I described above:
template<typename functorType, typename rreturnType, typename... aargs>
struct FunctorFunc : public FuncBase<rreturnType, aargs...>
{
functorType owner;
rreturnType run(aargs... arg) { return owner(arg...); }
FuncBase<rreturnType, aargs...>* clone() const { return new FunctorFunc<functorType, rreturnType, aargs...>(owner); }
FunctorFunc(functorType&& owner_) : owner(std::move(owner_)) {}
FunctorFunc(const functorType& owner_) : owner(owner_) {}
};
And here's the modified constructor:
template<typename functorType>
Runnable(functorType&& owner) { f = new FunctorFunc<functorType, returnType, args...>(std::forward<functorType>(owner)); }
Pay close attention to all the changes I had to make - they're all essential: where are things declared as references and where they're not, the use of std::forward and std::move. If something's not clear, ask me. The solution handles both rvalue and lvalue callable objects; rvalues would typically be lambdas, while lvalues may be some other types of callable objects that you construct separately.
Note that I also had to remove the const qualifier from the declaration of the run() member function. That's where the mutable part comes in: the function call operator for a non-mutable lambda is const, so it can be called on const functor objects. Once the lambda is declared mutable, that's no longer true, so owner cannot be const anymore, hence the removal of the qualifier from the function declaration.
And now we're getting to your second problem: you also have to remove the const qualifier from the declaration of the run() member function in the abstract base class FuncBase. Otherwise, you're actually declaring a different function in FunctorFunc, not overriding the one from the base. Because of this, FunctorFunc remains abstract (it still has a pure virtual function not defined); that's what the error message is trying to tell you.
To avoid running into this problem in the future, use the override specifier - it'll give you a clear error message.
EDIT: The constructor Runnable(functorType&& owner) is too generic, it can even act as a copy / move constructor in some cases. Here's a solution for restricting it using the SFINAE sledgehammer.
Initially, I thought I should restrict functorType to only match callable types that accept args... and return returnType as declared in the template parameters for the current instantiation of Runnable. To do that, the template parameters for the constructor should look like this:
template<typename functorType, typename = std::enable_if_t<
std::is_same<std::result_of_t<functorType(args...)>, returnType>::value>>
Alas, the current instantiation of Runnable is also a callable type satisfying that condition, and that's exactly what we want to avoid. So, the solution has to exclude this Runnable instantiation as well:
template<typename functorType, typename = std::enable_if_t<
!std::is_same<std::remove_cv_t<std::remove_reference_t<functorType>>, Runnable>::value &&
std::is_same<std::result_of_t<functorType(args...)>, returnType>::value>>
Runnables with the same template parameters as the current instantiation will fail the first test and Runnables with different template parameters will fail the second one, as will any callable type that doesn't have the correct parameters and return type. Maximum fun with type traits...
The code assumes you're using C++14, otherwise it would be (even) more verbose.
I want to write a template function that checks some Timestamp property (class inherits from Timed) but also has to work for types that do not have a timestamp. The best (and still quite ugly) solution I have found is the following:
class Timed {
protected:
int mTime;
public:
explicit Timed(int time=0): mTime(time){}
int getT() const {return mTime;}
};
template<typename T>
bool checkStale(T const* ptr) const {
return checkStaleImp(ptr, boost::is_base_of<Timed, T>() );
}
template<typename T>
template<bool b>
bool checkStaleImp(T const* ptr, boost::integral_constant<bool, b> const &){
return true;
}
template<typename T>
bool checkStaleImp(T const* ptr, boost::true_type const&){
const int oldest = 42;
return (42 <= ptr->getT());
}
This is three functions for one functionality. Is there an easier way to accomplish this, e.g. use boost::is_base_of or sth. similar in an if condition or boost::enable if to turn the function output into a sort of constant for classes not deriving from Timed. Solutions with virtual functions are unfortunately not an option.
You can do the same thing with two simple overloads and no template machinery:
bool checkStale(void const* ptr){
return true;
}
bool checkStale(Timed const* ptr){
const int oldest = 42;
return (oldest <= ptr->getT());
}
No need for tag dispatching on is_base_of.
I don't think that is quite ugly solution, as you said. However, you can reduce the scope of helper functions if you implement them as static member of local class as:
template<typename T>
bool checkStale(T const* ptr) const
{
struct local
{
static bool checkStaleImp(T const* ptr, boost::false_type const &)
{
return true;
}
static bool checkStaleImp(T const* ptr, boost::true_type const&)
{
const int oldest = 42;
return (42 <= ptr->getT());
}
};
return local::checkStaleImp(ptr, boost::is_base_of<Timed, T>());
}
Now, there is one function exposed for the user, and the actual implementation inside the local class.
By the way, in C++11, you can use std::is_base_of instead of boost's version. Same with std::true_type and std::false_type.
Use enable_if to select between possible overloads. Since the conditions used in the following example are complimentary there will always be exactly one overload available, and therefore no ambiguity
template<typename T>
typename std::enable_if<std::is_base_of<Timed,T>::value,bool>::type
checkStale(T const *ptr) const {
const int oldest = 42;
return oldest <= ptr->getT();
}
template<typename T>
typename std::enable_if<!std::is_base_of<Timed,T>::value,bool>::type
checkStale(T const *ptr) const {
return true;
}
Please, consider the code below:
template<typename T>
bool function1(T some_var) { return true; }
template <typename T>
bool (*function2())(T) {
return function1<T>;
}
void function3( bool(*input_function)(char) ) {}
If I call
function3(function2<char>());
it is ok. But if I call
function3(function2());
compiler gives the error that it is not able to deduction the argument for template.
Could you, please, advise (give an idea) how to rewrite function1 and/or function2 (may be, fundamentally to rewrite using classes) to make it ok?
* Added *
I am trying to do something simple like lambda expressions in Boost.LambdaLib (may be, I am on a wrong way):
sort(some_vector.begin(), some_vector.end(), _1 < _2)
I did this:
template<typename T>
bool my_func_greater (const T& a, const T& b) {
return a > b;
}
template<typename T>
bool my_func_lesser (const T& a, const T& b) {
return b > a;
}
class my_comparing {
public:
int value;
my_comparing(int value) : value(value) {}
template <typename T>
bool (*operator<(const my_comparing& another) const)(const T&, const T&) {
if (this->value == 1 && another.value == 2) {
return my_func_greater<T>;
} else {
return my_func_greater<T>;
}
}
};
const my_comparing& m_1 = my_comparing(1);
const my_comparing& m_2 = my_comparing(2);
It works:
sort(a, a + 5, m_1.operator< <int>(m_2));
But I want that it doesn't require template argument as in LambdaLib.
Deduction from return type is not possible. So function2 can't be deduced from what return type you expect.
It is however possible to deduce cast operator. So you can replace function2 with a helper structure like: Unfortunately there is no standard syntax for declaring cast operator to function pointer without typedef and type deduction won't work through typedef. Following definition works in some compilers (works in G++ 4.5, does not work in VC++ 9):
struct function2 {
template <typename T>
(*operator bool())(T) {
return function1<T>;
}
};
(see also C++ Conversion operator for converting to function pointer).
The call should than still look the same.
Note: C++11 introduces alternative typedef syntax which can be templated. It would be like:
struct function2 {
template <typename T>
using ftype = bool(*)(T);
template <typename T>
operator ftype<T>() {
return function1<T>;
}
};
but I have neither G++ 4.7 nor VC++ 10 at hand, so I can't test whether it actually works.
Ad Added:
The trick in Boost.Lambda is that it does not return functions, but functors. And functors can be class templates. So you'd have:
template<typename T>
bool function1(T some_var) { return true; }
class function2 {
template <typename T>
bool operator()(T t) {
function1<T>;
}
};
template <typename F>
void function3( F input_function ) { ... input_function(something) ... }
Now you can write:
function3(function2);
and it's going to resolve the template inside function3. All STL takes functors as templates, so that's going to work with all STL.
However if don't want to have function3 as a template, there is still a way. Unlike function pointer, the std::function (C++11 only, use boost::function for older compilers) template can be constructed from any functor (which includes plain function pointers). So given the above, you can write:
void function3(std::function<bool ()(char)> input_function) { ... input_function(something) ... }
and now you can still call:
function3(function2());
The point is that std::function has a template constructor that internally generates a template wrapper and stores a pointer to it's method, which is than callable without further templates.
Compiler don't use context of expression to deduce its template parameters. For compiler, function3(function2()); looks as
auto tmp = function2();
function3(tmp);
And it don't know what function2 template parameter is.
After your edit, I think what you want to do can be done simpler. See the following type:
struct Cmp {
bool const reverse;
Cmp(bool reverse) : reverse(reverse) {}
template <typename T> bool operator()(T a, T b) {
return reverse != (a < b);
}
};
Now, in your operator< you return an untyped Cmp instance depending on the order of your arguments, i.e. m_2 < m_1 would return Cmp(true) and m_1 < m_2 would return Cmp(false).
Since there is a templated operator() in place, the compiler will deduce the right function inside sort, not at your call to sort.
I am not sure if this help you and I am not an expert on this. I have been watching this post since yesterday and I want to participate in this.
The template cannot deduce it's type because the compiler does not know what type you are expecting to return. Following is a simple example which is similar to your function2().
template<typename T>
T foo() {
T t;
return t;
};
call this function
foo(); // no type specified. T cannot be deduced.
Is it possible to move the template declaration to the class level as follows:
template<typename T>
bool my_func_greater (const T& a, const T& b) {
return a > b;
}
template<typename T>
bool my_func_lesser (const T& a, const T& b) {
return b > a;
}
template <typename T>
class my_comparing {
public:
int value;
my_comparing(int value) : value(value) {}
bool (*operator<(const my_comparing& another) const)(const T&, const T&) {
if (this->value == 1 && another.value == 2) {
return my_func_greater<T>;
} else {
return my_func_greater<T>;
}
}
};
and declare m_1 and m_2 as below:
const my_comparing<int>& m_1 = my_comparing<int>(1);
const my_comparing<int>& m_2 = my_comparing<int>(2);
Now you can compare as follows:
if( m_1 < m_2 )
cout << "m_1 is less than m_2" << endl;
else
cout << "m_1 is greater than m_2" << endl;
I know this is simple and everyone knows this. As nobody posted this, I want to give a try.