SFINAE with features and emulation of partial template specialization

I am trying to make a function X that specializes when a member function Y is provided, and if a member function Y is not provided, the function X uses the global non-member function Y to achieve the same effect.

I am currently trying to achieve this with the following code

template <typename Container, typename std::enable_if_t<std::is_same<
            decltype(std::declval<Container>().y()),
            decltype(std::declval<Container>().y())>::value>* = nullptr>
void do_something(Container&& container) {
    return std::forward<Container>().y();
}

template <typename Container, typename std::enable_if_t<!std::is_same<
            decltype(std::declval<Container>().y()),
            decltype(std::declval<Container>().y())>::value>* = nullptr>
void do_something(Container&& container) {
    return y(std::forward<Container>(container);
}

But in the case when the container has both a member function y and a global non-member function y. Compilation error, because for the second version of the function, the template argument is poorly formed, because the member function y is needed.

Any idea how I can solve this problem?

. , . , , , ! .

+4
1

, , , - . , enable_if, decltype:

template <class C>
auto do_something_impl(C&& c, int)
    -> decltype(std::forward<C>(c).y())
{
    return std::forward<C>(c).y();
}

template <class C>
auto do_something_impl(C&& c, ...)
    -> decltype(y(std::forward<C>(c))
{
    return y(std::forward<C>(c));
}

0:

template <class C>
auto do_something(C&& c)
    -> decltype(do_something_impl(std::forward<C>(c), 0))
{
    return do_something_impl(std::forward<C>(c), 0);
}

int , , ..., , -, , , .

+3

Source: https://habr.com/ru/post/1658563/


All Articles