遍历 C++ 中的元组类型
Iterate over types of tuple in C++
我想遍历元组的类型,而不是它的元素。
假设您有一个通用的基础 class 接口 Controller
并且您想要一个指针向量(为了可读性,我使用原始指针而不是智能指针) : std::vector<Controller*> ctrls;
现在你想向这个向量添加 Controller
接口的许多实现,所以你可以这样做:
ctrls.emplace_back(new MouseCtrl());
ctrls.emplace_back(new KeyboardCtrl());
ctrls.emplace_back(new ScreenCtrl());
(... and so on)
但这很难看并且不能完全扩展(如开闭原则),因此最好有一个元组:using Controllers = std::tuple<MouseCtrl, KeyboardCtrl, ScreenCtrl>;
然后在一些初始化函数中,迭代这些类型:
for (T : Controllers> {
ctrls.emplace_back(new T());
}
显然,上面的代码不是有效的 C++ 语法。 所以问题是:如何做到这一点?。我已经研究了 std::apply 和 std::visit / std::variant,但我不知道该怎么做(它们遍历元素,而不是类型)。
您可以使用 std::tuple_size
和 std::tuple_element
来获取每个元组元素的类型(这会将其倒序排列,但稍加修改即可恢复顺序):
#include <iostream>
#include <variant>
#include <vector>
using namespace std;
using Controllers = tuple<int, char, float>;
using ControllersContainer = vector<variant<int, char, float>>;
template <size_t N>
void add(ControllersContainer& ctrls)
{
ctrls.emplace_back(tuple_element_t<N-1, Controllers>{});
add<N - 1>(ctrls);
}
template <>
void add<0>(ControllersContainer& ctrls)
{
ctrls.emplace_back(tuple_element_t<0, Controllers>{});
}
int main()
{
ControllersContainer ctrls;
add<tuple_size_v<Controllers>>(ctrls);
}
我想遍历元组的类型,而不是它的元素。
假设您有一个通用的基础 class 接口 Controller
并且您想要一个指针向量(为了可读性,我使用原始指针而不是智能指针) : std::vector<Controller*> ctrls;
现在你想向这个向量添加 Controller
接口的许多实现,所以你可以这样做:
ctrls.emplace_back(new MouseCtrl());
ctrls.emplace_back(new KeyboardCtrl());
ctrls.emplace_back(new ScreenCtrl());
(... and so on)
但这很难看并且不能完全扩展(如开闭原则),因此最好有一个元组:using Controllers = std::tuple<MouseCtrl, KeyboardCtrl, ScreenCtrl>;
然后在一些初始化函数中,迭代这些类型:
for (T : Controllers> {
ctrls.emplace_back(new T());
}
显然,上面的代码不是有效的 C++ 语法。 所以问题是:如何做到这一点?。我已经研究了 std::apply 和 std::visit / std::variant,但我不知道该怎么做(它们遍历元素,而不是类型)。
您可以使用 std::tuple_size
和 std::tuple_element
来获取每个元组元素的类型(这会将其倒序排列,但稍加修改即可恢复顺序):
#include <iostream>
#include <variant>
#include <vector>
using namespace std;
using Controllers = tuple<int, char, float>;
using ControllersContainer = vector<variant<int, char, float>>;
template <size_t N>
void add(ControllersContainer& ctrls)
{
ctrls.emplace_back(tuple_element_t<N-1, Controllers>{});
add<N - 1>(ctrls);
}
template <>
void add<0>(ControllersContainer& ctrls)
{
ctrls.emplace_back(tuple_element_t<0, Controllers>{});
}
int main()
{
ControllersContainer ctrls;
add<tuple_size_v<Controllers>>(ctrls);
}