I’m trying hard for some hours and didn’t manage to get this working.
I have a templated class spinlock:
template<typename T> class spinlock {
// ...
volatile T *shared_memory;
};
I’m trying to create something like this:
// inside spinlock class
template<typename F, typename... Ars>
std::result_of(F(Args...))
exec(F fun, Args&&... args) {
// locks the memory and then executes fun(args...)
};
But I’m trying to use a polymorphic function so that I can do this:
spinlock<int> spin;
int a = spin.exec([]() {
return 10;
});
int b = spin.exec([](int x) {
return x;
}, 10); // argument here, passed as x
// If the signature matches the given arguments to exec() plus
// the shared variable, call it
int c = spin.exec([](volatile int &shared) {
return shared;
}); // no extra arguments, shared becomes the
// variable inside the spinlock class, I need to make
// a function call that matches this as well
// Same thing, matching the signature
int d = spin.exec([](volatile int &shared, int x) {
return shared + x;
}, 10); // extra argument, passed as x... should match too
// Here, there would be an error
int d = spin.exec([](volatile int &shared, int x) {
return shared + x;
}); // since no extra argument was given
Basically, I’m trying to make an exec function that accepts F(Args...) or F(volatile T &, Args...) as an argument.
But I can’t manage to make automatic detection of types.
How could I accomplish that?
Firstly, this signature will not compile:
The return type needs to be
If your compiler implements N3436 then this function will not participate in overload resolution when
fun(args...)is not a valid expression, but that is not required in C++11 and not implemented by many compilers yet. You will need to implement your own SFINAE check to preventresult_ofgiving an error whenfun(args...)is not valid, or rewrite it withoutresult_ofThen you can overload it for functions that need the additional parameter passed in:
When
fun(std::forward<Args>(args)...)is not valid the first overload will not participate in overload resolution. Whenfun(*this->shared_memory, std::forward<Args>(args)...)is not valid the second overload will not participate in overload resolution. If neither is valid the call will be ill-formed, if both are valid the call will be ambiguous.