以下是根据您的建议实现的一个使用 std::tuple
的模板类工作示例:
#include <iostream>
#include <utility>
#include <vector>
#include <tuple>
void f0() {
std::cout << "f0\n";
}
void f1(int a) {
std::cout << "f1: " << a << '\n';
}
void f2(int a, int b) {
std::cout << "f2: " << a + b << '\n';
}
void f3(const std::string& a, int b) {
std::cout << "f3: " << a << " ** " << b << '\n';
}
// 移除元组第一个元素并将剩余元素重新打包成新元组
template <typename T1, typename... Ts>
std::tuple<Ts...> unshift_tuple(const std::tuple<T1, Ts...>& tuple)
noexcept
{
return std::apply(
[](auto&&, const auto&... args) {
return std::tie(args...);
},
tuple
);
}
// 使用元组中的元素作为参数调用可调用对象
template <typename Callable, typename... Params>
void call(const std::tuple<Callable, Params...>& t) noexcept {
const auto& f = std::get<0>(t);
const auto args = unshift_tuple(t);
std::apply(f, args);
}
// 执行器类,接受多个函数及参数
template <typename... Params>
class Execute {
public:
Execute(std::tuple<Params...>&& t) : m_fs(std::move(t)) { }
void execute() noexcept {
iterate_over_functions<0>(m_fs);
}
private:
// 递归调用函数
template <std::size_t I, typename... Ts>
void iterate_over_functions(const std::tuple<Ts...>& t) noexcept {
if constexpr (I < sizeof...(Ts)) {
call(std::get<I>(t));
iterate_over_functions<I + 1>(t);
}
}
private:
std::tuple<Params...> m_fs;
};
int main() {
Execute e(
std::make_tuple(
std::make_tuple(f0),
std::make_tuple(f1, 1),
std::make_tuple(f2, 1, 2),
std::make_tuple(f3, "Stack Overflow!", 2)
)
);
e.execute();
}
注意:为了从元组中获取参数并使用 std::apply
调用函数,需要了解如何移除元组的第一个元素并将剩余元素重新打包成新元组。这个解决方案中,您正确地实现了这一点,并创建了一个能够按照指定顺序执行多个函数的 Execute
类。