Reputation: 115
I am trying to make a templated variadic with a changing return type. If the number of arguments is 1 then it should return a pointer to the only argument, otherwise it should return a tuple of pointer of the argument:
int var = 0;
A *ptr_A = foo<A>(var);
auto *[ptr_A, ptr_B] = foo<A, B>(var);
and this is the code i have so far
template<typename T>
T* AddComp(EntityId entityID)
{
componentPool<T>* pool = GetOrCreatePool<T>();
return pool->Create(entityID);
}
template <typename... Args>
decltype(auto) AddComponent(EntityId entityID)
{
if constexpr (sizeof...(Args) == 1)
{
return AddComp <Args>(entityID);
}
else
{
return std::tuple<decltype(AddComponent<Args>({}))... > {AddComponent<Args>(entityID)...};
}
}
But i am getting several errors:
In case of A *ptr_A = foo<A>(var);
VS says that he cannot convert from void to A*, which says that decltype(auto) is somehow becoming void
And in return AddComp <Args>(entityID);
VS says that Args parameter pack must be expanded. Do i still need to somehow expand Args even if its a single parameter?
Thank you!
Edit:
As asked i am providing a minimal example
using EntityId = size_t;
class A
{
public:
int a;
};
class B
{
public:
int b;
};
class componentsManager
{
public:
template<typename T>
T* AddComp(EntityId entityID)
{
return new T();
}
template <typename... Args>
decltype(auto) AddComponent(EntityId entityID)
{
if constexpr (sizeof...(Args) == 1)
{
return AddComp <Args>(entityID);
}
else
{
return std::tuple<decltype(AddComponent<Args>({}))... > {AddComponent<Args>(entityID)...};
}
}
};
componentsManager m_manager;
EntityId id;
A *ptr_A1 = m_manager.AddComponent <A>(id);
auto *[ptr_A2, ptr_B] = m_manager.AddComponent<A, B>(id);// This will only compile in c++17 i believe, i am using c++14
Edit2:
Upvotes: 1
Views: 180
Reputation: 52621
The straightforward
if constexpr (sizeof...(Args) == 1)
{
return AddComp<Args...>(entityID);
}
appears to work just fine. Clang demo, MSVC demo
Here's a solution that works with C++14:
template <typename T>
decltype(auto) AddComponent(EntityId entityID)
{
return AddComp<T>(entityID);
}
template <typename... Args>
decltype(auto) AddComponent(
std::enable_if_t<(sizeof...(Args) > 1), EntityId> entityID)
{
return std::tuple<decltype(AddComponent<Args>({}))...>{
AddComponent<Args>(entityID)...};
}
Upvotes: 1