c++ 这在std::tuple; element 'has'成员中是如何工作的?

pcrecxhr  于 2024-01-09  发布在  其他
关注(0)|答案(1)|浏览(134)

我最近在网上看到这个例子:

  1. typedef std::tuple<
  2. CInput,
  3. CAnimation,
  4. CTransform
  5. > ComponentTuple;
  6. class Entity
  7. {
  8. ...
  9. ComponentTuple m_components;
  10. public:
  11. ...
  12. // component management
  13. template <typename T> bool has_component() const { return get_component<T>().has; }
  14. template <typename T, typename... TArgs> T& add_component(TArgs&&... mArgs)
  15. {
  16. auto& component = get_component<T>();
  17. component = T(std::forward<TArgs>(mArgs)...);
  18. component.has = true;
  19. return component;
  20. }
  21. template <typename T> T& get_component() { return std::get<T>(m_components); }
  22. template <typename T> const T& get_component() const { return std::get<T>(m_components); }
  23. template <typename T> void remove_component() { get_component<T>() = T(); }
  24. };

字符串
我已经研究了几个小时的代码,我不能弄清楚模板成员has_component和add_component是如何工作的-特别是has成员。这是从哪里来的?它没有在标准中记录,我可以看到的任何地方。然而,不知何故,has成员在add_component中被设置为true,并且可以在has_component中检查。
显然,这里的目标是使用has来确定元组条目是否是默认构造的。

vhmi4jdf

vhmi4jdf1#

在这里提供一些结束。User@user17732522提供了我需要的线索来弄清楚发生了什么,以及使用std::optional的更好实现的建议:

  1. #include <tuple>
  2. #include <optional>
  3. typedef std::tuple<
  4. std::optional<CInput>,
  5. std::optional<CAnimation>,
  6. std::optional<CTransform>
  7. > ComponentTuple;
  8. class Entity
  9. {
  10. ...
  11. ComponentTuple m_components;
  12. public:
  13. ...
  14. // component management
  15. template <typename T> bool has_component() const { return std::get<std::optional<T>>(m_components).has_value(); }
  16. template <typename T, typename... TArgs> T& add_component(TArgs&&... mArgs)
  17. {
  18. std::optional<T>& opt_comp = std::get<std::optional<T>>(m_components);
  19. opt_comp = std::make_optional(T(std::forward<TArgs>(mArgs)...));
  20. return opt_comp.value();
  21. }
  22. template <typename T> T& get_component() { return std::get<std::optional<T>>(m_components).value(); }
  23. template <typename T> const T& get_component() const { return std::get<std::optional<T>>(m_components).value(); }
  24. template <typename T> void remove_component() { std::get<std::optional<T>>(m_components).reset(); }
  25. };

字符串
在这个实现中,元组可以管理的类型绝对没有任何限制,除了每个类型必须是唯一的,这样成员就可以通过类型而不是索引找到元素。
代码可以这样写:

  1. auto& anim = player->add_component<CAnimation>(...);
  2. std::cout << "added: " << anim << std::endl;
  3. std::cout << "player " << (player->has_component<CAnimation>() ? "has" : "does not have") << " the CAnimation component." << std::endl;
  4. player->remove_component<CAnimation>();
  5. std::cout << "removed" << std::endl;
  6. std::cout << "player " << (player->has_component<CAnimation>() ? "has" : "does not have") << " the CAnimation component." << std::endl;


非常感谢那些回答的人。

展开查看全部

相关问题