Here is some code that compiles in GCC (on godbolt at least - can't test locally), for handling a compile-time dependency system - the conversion operator here is to make it easier to take an entity that specifies what it can read/write and reduce it down implicitly to a more restricted form when passing into functions (please pretend that the operator below does some static_assert kind of enforcement).
template<typename... Args>
struct WriteList{};
template<typename... Args>
struct ReadList{};
template<typename Reads = ReadList<>, typename Writes = WriteList<>>
class TypedEntity;
template <typename... ReadTypes, template <typename...> typename Reads, typename... WriteTypes, template <typename...> typename Writes>
class TypedEntity<Reads<ReadTypes...>, Writes<WriteTypes...>>
{
public:
template <typename... OtherReadTypes, typename... OtherWriteTypes>
operator TypedEntity<ReadList<OtherReadTypes...>, WriteList<OtherWriteTypes...>>()
{
return {};
}
};
struct ComponentA{};
struct ComponentB{};
struct ComponentC{};
void TestFunc1(TypedEntity<ReadList<ComponentA, ComponentB>, WriteList<ComponentC>> entity)
{
}
void TestFunc2(TypedEntity<ReadList<ComponentA>, WriteList<>> entity)
{
}
void TestFunc3(TypedEntity<ReadList<ComponentA>, WriteList<ComponentC>> entity)
{
}
int main()
{
TypedEntity<ReadList<ComponentA, ComponentB>, WriteList<ComponentB>> entity;
TestFunc1(entity);
TestFunc2(entity);
TestFunc3(entity);
return 0;
}
But under MSVC (latest, i.e.g 19.28, as well as some other 19.x versions I've sampled (19.14, 19.24, etc)):
error C3547: template parameter 'OtherWriteTypes' cannot be used because it follows a template parameter pack and cannot be deduced from the function parameters of 'TypedEntity<Reads<ReadTypes...>,Writes<WriteTypes...>>::operator TypedEntity<ReadList<OtherReadTypes...>,WriteList<OtherWriteTypes...>>'
- Is this valid C++ and MSVC is wrong?
- Is there a workaround for this issue in MSVC?
Appreciate it.