N
N
Nexeon2016-11-15 18:37:46
C++ / C#
Nexeon, 2016-11-15 18:37:46

Using variadic function template with no arguments?

I have a class object Entitythat contains a list of components. std::list<Component*> m_components
The components themselves are classes that inherit from the base class. Component
With the help of a function, bool HasComponent<T>I can check for the presence of a specific component:

template<typename T> bool HasComponent<T> {
 T instance; //создаю экземпляр компонента

 for (auto component : m_components)  //for each 
 if (component->GetType() == instance.GetType()) { //если типы компонентов совпадают
 return true; //возвращаем true
}

//...

Entity mario;
if (mario.HasComponent<Velocity>) print("Mario can move!"); //пример использования

But how can I check the presence of several components at once with one function?
bool HasComponents<Health, Velocity, Sprite>();
I know this can be done with variadic templates , but I only find them useful with arguments like this: void foo(Args... args).
Question: How to implement the algorithm for my case?

Answer the question

In order to leave comments, you need to log in

3 answer(s)
E
Evgeny Shatunov, 2016-11-15
@MrNexeon

Look... in the proposed code, I already see a bit of a mess, so I suggest a slightly messy option. :)
This problem can be solved by several methods of metaprogramming at once. The proposed solution is one of them.

template< typename TComponentType >
bool HasComponent()
{
  return ...;
};

template< typename... TComponentTypes >
bool HasComponents()
{
  // Это тип предиката для проверки наличия одного компонента.
  using CheckingPred	= bool (*)();
  
  // Это тип листа проверки.
  using PredList		= std::array<CheckingPred, sizeof...( TComponentTypes )>;
  
  // Определяем лист проверки, следи за руками... :-)
  PredList predicates{{ HasComponent<TComponentTypes>... }};
  
  // Проверяем!
  return std::all_of( predicates.begin(), predicates.end(), []( CheckingPred stored_pred ) -> bool { return stored_pred(); } );
};

I immediately focus on formatting and style. So to say, what is clearer and easier to read? :)
I also suggest looking through the library of one interesting friend: https://github.com/alecthomas/entityx
As I understand it, you want to try to implement ECS. EntityX is one of the most direct ECS libraries on the plus side, if not the most direct one.

M
MiiNiPaa, 2016-11-15
@MiiNiPaa

For example in C++17:
1) Rename your current HasComponent to HasComponent_impl and make it private.
2) Create a new HasComponent:

template<typename... Ts> bool HasComponent()
{
    return (HasComponent_impl<Ts>() && ...);
}
Example.
Quadratic complexity, of course. It can be done better, but is it necessary?

A
Adamos, 2016-11-15
@Adamos

In your case, I would turn off the lamp in front of Alexandrescu's portrait and stop raping the compiler.
By achieving your goal, you obfuscate the code - and at the same time you definitely do not win anything.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question