英文:
How to create a template that takes two different signatures for a callback
问题
Here's the translated content you requested:
我有一个执行器,它接受一个要运行的函数。它支持两种签名,取决于回调函数是否需要会话对象。
template<typename T, typename S>
T run(const std::function<T(Client&)>& f, S s);
template<typename T, typename S>
T run(const std::function<T(Client&, const S&)>& f, S s);
我想要有一个函数来包装这两个函数(比如用于重试),但我不想重复编写它们,因为它们是相同的:
template <typename T, typename S>
T runWithRetry(const std::function<T(Client&)>& f, S s) {
for (;;) {
try {
return run(f, s);
} catch (Retry &e) {}
}
}
template <typename T, typename S>
T runWithRetry(const std::function<T(Client&, const S&)>& f, S s) {
for (;;) {
try {
return run(f, s);
} catch (Retry &e) {}
}
}
这是我想要解决的实际问题。
我尝试将回调函数设为模板,但随后我需要一种获取返回类型的方法:
template <typename F, typename S>
return_type<F>::type runWithRetry(const F& f, S s);
那么如何实现return_type?我想要类似以下的东西:
template <typename F, typename S> struct return_type {
using type = decltype(std::declval<F>(std::declval<Client>)) || decltype(std::declval<F>(std::declval<Client>, std::declval<S>))
}
但我无法弄清楚如何表达它。
我可以使用C++20。
英文:
I have an executor that takes a function to run. It supports two signatures depending on whether the callback wants the session object.
template<typename T, typename S>
T run(const std::function<T(Client&)>& f, S s);
template<typename T, typename S>
T run(const std::function<T(Client&, const S&)>& f, S s);
I want to have a function wrap these two (say for retries) but I don’t want to write it twice since they are the same:
template <typename T, typename S>
T runWithRetry(const std::function<T(Client&)>& f, S s) {
for (;;) {
try {
return run(f, s);
} catch (Retry &e) {}
}
}
template <typename T, typename S>
T runWithRetry(const std::function<T(Client&, const S&)>& f, S s) {
for (;;) {
try {
return run(f, s);
} catch (Retry &e) {}
}
}
This is the actual problem I want to solve.
I tried making the callback a template but then I needed a way to get the return type:
template <typename F, typename S>
return_type<F>::type runWithRetry(const F& f, S s);
So how to implement return_type? I wanted something like:
template <typename F, typename S> struct return_type {
using type = decltype(std::declval<F>(declval<Client>)) || decltype(std::declval<F>(declval<Client>, declval<S>)
}
But I couldn’t figure out how to express that.
I can use C++20.
答案1
得分: 4
如果您可以使用C++20,那么您无需担心返回类型,它可以使用auto
进行推断。这将给您提供:
template <typename F, typename S>
auto runWithRetry(const F& f, S s) {
for (;;) {
try {
return run(f, s);
} catch (Retry &e) {}
}
}
现在返回类型将是run(f, s)
的推断返回类型。如果run
可以返回引用,并且您希望保留它,那么您需要将返回类型更改为decltype(auto)
,而不仅仅是auto
。
英文:
If you can use C++20, then you don't need to worry about the return type, it can be deduced for you using auto
. That gives you
template <typename F, typename S>
auto runWithRetry(const F& f, S s) {
for (;;) {
try {
return run(f, s);
} catch (Retry &e) {}
}
}
And now the return type will be the deduced return type of run(f, s)
. If run
can return a reference, and you want to keep that, then you need to use decltype(auto)
as the return type instead of just auto
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论