I was reading somewhere that it would be possible to do c++ metaprogramming using function overloads instead of SFINAE. I came up with a toy exercise to test this. I want to detect if a particular type is a nested vector. My code that works is
#include <type_traits>
#include <vector>
#include <iostream>
template <typename T> struct Tag {};
template <typename TLeaf >
consteval bool is_nested(Tag<TLeaf>)
{
return true;
}
template <typename TLeaf , typename TSub, typename enable = std::enable_if_t< !std::is_same_v<TLeaf, TSub> >>
consteval bool is_nested(Tag<TSub>)
{
return false;
}
template <typename TLeaf , typename TSub>
consteval bool is_nested(Tag<std::vector<TSub>>)
{
return is_nested<TLeaf>(Tag<TSub>{});
}
template <typename TSub, typename TLeaf>
consteval bool is_nested()
{
return is_nested<TLeaf>(Tag<TSub>{});
}
int main(){
using type_nested1 = std::vector<std::string>;
using type_nested2 = std::vector<type_nested1>;
std::cout << is_nested<type_nested1, std::string>() << std::endl;
std::cout << is_nested<type_nested2, std::string>() << std::endl;
std::cout << is_nested<int, std::string>() << std::endl;
std::cout << is_nested<type_nested1, int>() << std::endl;
std::cout << is_nested<type_nested2, int>() << std::endl;
}
https://godbolt.org/z/zGEf9cej5
and the output is
Program returned: 0
Program stdout
1
1
0
0
0
but I'm disappointed that I had to use std::enable_if_t
to disambiguate the two overloads. Can this be rewritten to keep the spirit of the exercise but eliminate any SFINAE crud from the solution?