In my program I have a lot of pointers to functions provided by an external library. Some of them return value, and some of them not.
If external library did not provide function (pointer is NULL) and function should return value program should assume default value (which is known at compile time).
What I try to accomplish is to reduce amount of if
statements and to wrap pointer in class with following use case:
enum E { e1, e2, e3 };
UserFunction<uint8_t(int, int), 0> callback1 { user_function_ptr }; // Calls and returns value of user_function_ptr
UserFunction<uint8_t(), 0> callback2 { nullptr }; // Returns 0
UserFunction<uint8_t(), 1> callback3 { nullptr }; // Returns 1
UserFunction<E(int), e1> callback4 { user_function_ptr2 }; // Returns enum value and takes one integer argument
UserFunction<void(int)> callback5 { user_function_ptr3 }; // No return value, one argument
UserFunction<void()> callback6 { nullptr }; // Should perform noop
What I got so far is working for functions that return value:
template <class Sign, int Def>
struct UserF;
template <class R, int Def, class... Args>
struct UserF<R(Args...), Def> {
typedef R Signature(Args...);
typedef typename std::add_pointer<Signature>::type SignaturePtr;
static R Default(Args... args) {
return (R) Def;
}
UserF() {
functionToCall = Default;
}
UserF(SignaturePtr userFunction) {
if (userFunction != nullptr) {
functionToCall = userFunction;
} else {
functionToCall = Default;
}
}
R operator() (Args... args) {
return functionToCall(args...);
}
private:
SignaturePtr functionToCall;
};
The problem with code above is that it forces default value to be int
. What I could do is change UserF
template to something like this:
template <class R, R Def, class... Args>
struct UserF {
// ...
};
// use case
UserF<E, e1, int> callback; // Returns E, takes int, default e1
But if it possible I would rather use
UserF<R(Args...), Default> callback; // preferred
UserF<Default, R(Args...)> callback; // if above is not possible
UserF<void(Args...)> callback; // if no return value
I would rather not use std::function
since I know that I will be dealing only with pointers to functions, and not with pointers to member functions, functor objects, etc. Also boost is not allowed (C++11 is allowed).
To summarize, the question is: How to force type check on default return value.
Aucun commentaire:
Enregistrer un commentaire