I need a template to find out the order of types in which the class inherits from its bases and their index. The code works fine with clang and gcc but in Visual Studio, which is the target environment, I'm getting an internal compiler error "fatal error C1001: An internal error has occurred in the compiler.". I'm looking for some workaround or maybe an error in my code. Yes, I have already tried google.
Thanks, in advance.
#include <type_traits>
#include <iostream>
struct BaseA
{
};
struct BaseB
{
};
struct BaseC
{
};
template <class... Types>
class type_list {};
template<typename Type, typename TypeList>
struct get_idx_for_type;
template<typename Type, template<typename...> typename TypeList, typename ...Types>
struct get_idx_for_type<Type, TypeList<Types...>>
{
template<int I, typename T, typename ...Rest>
struct find_type;
template<int I, typename T, typename U, typename ...Rest>
struct find_type< I, T, U, Rest... >
{
// problematic line for compiler, problem is somewhere in find_type recursion
static constexpr int value = std::is_same<T, U>::value ? I : find_type<I + 1, T, Rest...>::value;
};
template<int I, typename T, typename U>
struct find_type< I, T, U >
{
static constexpr int value = std::is_same<T, U>::value ? I : -1;
};
static constexpr int value = find_type<0, Type, Types...>::value;
};
template<typename ...Bases>
struct Foo : public Bases...
{
using base_types_list = type_list<Bases...>;
};
int main()
{
using T = Foo<BaseA, BaseB, BaseC>;
Foo<BaseA, BaseB, BaseC> q;
int a = get_idx_for_type<BaseA, T::base_types_list>::value;
std::cout << a << std::endl;
return 0;
}
An internal compiler error is always a bug in the compiler, whether or not there is anything wrong with your code. To work around this one, you can replace:
template<int I, typename T, typename U, typename ...Rest>
struct find_type< I, T, U, Rest... >
{
// problematic line for compiler, problem is somewhere in find_type recursion
static constexpr int value = std::is_same<T, U>::value ? I : find_type<I + 1, T, Rest...>::value;
};
with:
template<int I, typename T, typename U, typename V, typename ...Rest>
struct find_type< I, T, U, V, Rest... >
{
static constexpr int value = std::is_same<T, U>::value ? I : find_type<I + 1, T, V, Rest...>::value;
};
to assist VC++ in disambiguating it from:
template<int I, typename T, typename U>
struct find_type< I, T, U >
{
static constexpr int value = std::is_same<T, U>::value ? I : -1;
};
when ...Rest is empty.
Live demo
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With