我正在努力工作几个小时,并没有设法让这个工作。
我有一个模板类spinlock:
template<typename T> class spinlock {
// ...
volatile T *shared_memory;
};
我正在尝试创建这样的东西:
// 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...)
};
但我正在尝试使用多态函数,以便我可以这样做:
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
基本上,我正在尝试制作一个exec
函数,接受F(Args...)
或F(volatile T &, Args...)
作为参数。
但我无法自动检测类型。 我怎么能做到这一点?
答案 0 :(得分:3)
首先,这个签名不会编译:
// 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...)
};
返回类型需要
typename std::result_of<F(Args...)>::type
如果您的编译器实现N3436,那么当fun(args...)
不是有效表达式时,此函数将不参与重载解析,但这在C ++ 11中不是必需的,并且还没有被许多编译器实现。您需要实施自己的SFINAE检查,以防止result_of
在fun(args...)
无效时发出错误,或在没有result_of
的情况下重写
template<typename F, typename... Args>
auto
exec(F fun, Args&&... args) -> decltype(fun(std::forward<Args>(args)...))
{
// locks the memory and then executes fun(args...)
}
然后,您可以为需要传入其他参数的函数重载它:
template<typename F, typename... Args>
auto
exec(F fun, Args&&... args) -> decltype(fun(*this->shared_memory, std::forward<Args>(args)...))
{
// locks the memory and then executes fun(*shared_memory, args...)
}
当fun(std::forward<Args>(args)...)
无效时,第一个重载将不参与重载解析。当fun(*this->shared_memory, std::forward<Args>(args)...)
无效时,第二个重载将不参与重载解析。如果两者都无效,则呼叫将是格式错误的,如果两者都有效,则呼叫将是不明确的。