'How to use concepts in if statement

I have a concept which checks whether a type is iterable or not

template<typename T>
concept Iterable = requires(T t) {
    t.begin();
};

I cannot use it in a template due to problems with overloading, so I'd like to do something similar to the following:

template<typename T>
void universal_function(T x) {
    if (x is Iterable)
        // something which works with iterables
    else if (x is Printable)
       // another thing
    else
       // third thing
}


Solution 1:[1]

You can directly write the requires clause inside the if to determine the validity of the expression, something like this

template<typename T>
void universal_function(T x) {
    if constepxr (requires {  x.begin(); }) {
        // something which works with iterables
    }
    else if constepxr (requires {  std::cout << x; }) {
       // another thing
    }
    else {
       // third thing
    }
}

But it seems that only detecting whether x.begin() is well-formed is not enough for iterable types, the standard library already has a concept for this, namely std::ranges::range:

if constepxr (std::ranges::range<T>) {
   // something which works with iterables
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1