C++ lambda 在模板函数中作为 std::function
C++ lambda as std::function in template function
假设我们有我的代码的这个简化版本:
template<typename R>
R Context::executeTransient(std::function<R(VkCommandBuffer)> const &commands) {
...
R result = commands(commandBuffer);
...
return result;
}
我试图将 lambda 函数作为参数传递给函数 Context::executeTransient()
,但只有当我将 lambda 显式分配给特定的 std::function
类型时它才有效。这有效:
std::function<int(VkCommandBuffer)> f = [](VkCommandBuffer commandBuffer) {
printf("Test execution");
return 1;
};
context.executeTransient(f);
上面的例子可行,但出于审美原因我想实现下面的例子,但不知道这是否可行:
context.executeTransient([](VkCommandBuffer commandBuffer) {
printf("Test execution");
return 1;
});
我唯一的要求是 Context::executeTransient()
应该接受具有模板化 return 类型的 lambda 和函数以及具有某些特定类型的输入参数,例如VkCommandBuffer
.
那么简单如下呢?
template <typename F>
auto Context::executeTransient (F const & commands) {
...
auto result = commands(commandBuffer);
...
return result;
}
这样你的方法接受标准函数和 lambdas(不将它们转换为标准函数,从性能的角度来看(据我所知)这是更可取的)并且 return 类型是从使用推导出 (auto
).
如果您需要知道方法中的 R
类型,您可以将 decltype()
应用于 result
auto result = commands(commandBuffer);
using R = decltype(result);
如果您需要知道 R
类型作为方法的模板参数,它会稍微复杂一些,因为涉及 std::declval()
,不幸的是,添加冗余
template <typename F,
typename R = decltype(std::declval<F const &>()(commandBuffer))>
R Context::executeTransient (F const & commands) {
...
R result = commands(commandBuffer);
...
return result;
}
假设我们有我的代码的这个简化版本:
template<typename R>
R Context::executeTransient(std::function<R(VkCommandBuffer)> const &commands) {
...
R result = commands(commandBuffer);
...
return result;
}
我试图将 lambda 函数作为参数传递给函数 Context::executeTransient()
,但只有当我将 lambda 显式分配给特定的 std::function
类型时它才有效。这有效:
std::function<int(VkCommandBuffer)> f = [](VkCommandBuffer commandBuffer) {
printf("Test execution");
return 1;
};
context.executeTransient(f);
上面的例子可行,但出于审美原因我想实现下面的例子,但不知道这是否可行:
context.executeTransient([](VkCommandBuffer commandBuffer) {
printf("Test execution");
return 1;
});
我唯一的要求是 Context::executeTransient()
应该接受具有模板化 return 类型的 lambda 和函数以及具有某些特定类型的输入参数,例如VkCommandBuffer
.
那么简单如下呢?
template <typename F>
auto Context::executeTransient (F const & commands) {
...
auto result = commands(commandBuffer);
...
return result;
}
这样你的方法接受标准函数和 lambdas(不将它们转换为标准函数,从性能的角度来看(据我所知)这是更可取的)并且 return 类型是从使用推导出 (auto
).
如果您需要知道方法中的 R
类型,您可以将 decltype()
应用于 result
auto result = commands(commandBuffer);
using R = decltype(result);
如果您需要知道 R
类型作为方法的模板参数,它会稍微复杂一些,因为涉及 std::declval()
,不幸的是,添加冗余
template <typename F,
typename R = decltype(std::declval<F const &>()(commandBuffer))>
R Context::executeTransient (F const & commands) {
...
R result = commands(commandBuffer);
...
return result;
}