Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

enable_if and auto return type?

I want to use type_traits to overload by shared_ptr or not.

struct A {
    A(int i) : x(i) {}
    int x;
};

int main()
{
    A a{4};
    auto b = std::make_shared<A>(7);
    A& c = a;
    A* d = b.get();
    A* e = &a;

    std::cout << getX(a) << std::endl;
    std::cout << getX(b) << std::endl;
    std::cout << getX(c) << std::endl;
    std::cout << getX(d) << std::endl;
    std::cout << getX(e) << std::endl;

    return 0;
}

This is one solution but has the problem that the return type must be pre-defined.

template <typename T>
typename std::enable_if_t<!boost::has_dereference<T>::value, int> getX(T t)
{
    return t.x;
}

template <typename T>
typename std::enable_if_t<boost::has_dereference<T>::value, int> getX(T t)
{
    return t->x;
}

But using the method below, I can make the return type auto but it kind of looks clunky.

template <typename T, typename std::enable_if_t<!boost::has_dereference<T>::value>* = nullptr>
auto getX(T t)
{
    return t.x;
}

template <typename T, typename std::enable_if_t<boost::has_dereference<T>::value>* = nullptr>
auto getX(T t)
{
    return t->x;
}

Is there a method to use the first type and still get return type auto?

I do not want to specify the type of A::x and so auto return type would be best. The second type does that but feels a bit clunky.

Or is there a better way of doing this? Thanks.

like image 272
Mochan Avatar asked Oct 28 '25 07:10

Mochan


1 Answers

If you just want to run a different line of code or two for different types then constexpr if lets you do that without having to use enable_if and allows you to use automatic return type deduction. You can simplify getX into

template <typename T>
auto getX(T t)
{
    if constexpr (boost::has_dereference<T>::value)
        return t->x;
    else
        return t.x;
}

and this works because the path that is not executed is discarded so at compile time only the true path compiled.

like image 69
NathanOliver Avatar answered Oct 31 '25 12:10

NathanOliver



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!