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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With