When I try and get the index of a type within a list of types using below, the code compiles and returns the correct value when the else clause is used. However when I skip the else clause and place the return getIndex<T, Ts...>(x + 1); just after the end of the if clause the code fails to compile as it continues to unwind getIndex<T, Ts...> recursively resulting in the error shown below. This is the case with gcc and clang. Is this expected?
#include <type_traits>
template <typename T, typename U, typename ...Ts>
constexpr int getIndex(int x = 0)
{
if constexpr(std::is_same_v<T,U>)
{
return x;
}
else
{
return getIndex<T, Ts...>(x + 1);
}
}
int main()
{
return getIndex<int, float, double, int, char>();
}
Error when moving return outside of else
getI.cc: In instantiation of ‘int getIndex(int) [with T = int; U = char; Ts = {}]’:
getI.cc:9:32: recursively required from ‘int getIndex(int) [with T = int; U = double; Ts = {int, char}]’
getI.cc:9:32: required from ‘int getIndex(int) [with T = int; U = float; Ts = {double, int, char}]’
getI.cc:14:51: required from here
getI.cc:9:32: error: no matching function for call to ‘getIndex<int>(int)’
9 | return getIndex<T, Ts...>(x + 1);
| ~~~~~~~~~~~~~~~~~~^~~~~~~
getI.cc:3:5: note: candidate: ‘template<class T, class U, class ... Ts> int getIndex(int)’
3 | int getIndex(int x = 0)
| ^~~~~~~~
getI.cc:3:5: note: template argument deduction/substitution failed:
getI.cc:9:32: note: couldn’t deduce template parameter ‘U’
9 | return getIndex<T, Ts...>(x + 1);
| ~~~~~~~~~~~~~~~~~~^~~~~~~