Is there any way to check if an arbitrary variable type is iterable?
So to check if it has indexed elements or I can actually loop over it\'s children? (Use foreach
If you are under the umbrella of C++11 and beyond, one usual way of SFINAE checking that works when you have to specialize for just one property, is the following one:
template)>
inline constexpr bool expression_works(int) { return true; }
template
inline constexpr bool expression_works(unsigned) { return false; }
template(42)>
class my_class;
template
struct my_class
{ /* Implementation when true */ };
template
struct my_class
{ /* Implementation when false */ };
The trick is as follow:
false.42 has type int, and thus int is a better match than unsigned, getting true.42 because it's the answer to everything, inspired by Eric Niebler's range implementation. In your case, C++11 has the free functions std::begin and std::end that works for arrays and containers, so the expression that must work is:
template()))
inline constexpr bool is_iterable(int) { return true; }
template
inline constexpr bool is_iterable(unsigned) { return false; }
If you need more generality, a way to express that something is iterable could also include user-defined types that brings their own overloads for begin and end, so you need to apply some adl here:
namespace _adl_begin {
using std::begin;
template
inline auto check() -> decltype(begin(std::declval())) {}
}
template())>
inline constexpr bool is_iterable(int) { return true; }
template
inline constexpr bool is_iterable(unsigned) { return false; }
You can play with this technique to achieve solutions that fits better your actual context.