Can I overload function templates based on properties?

Viewed 41

I want to get a common property from different families of classes. For some, I can just use a member, for some I need to call a function. Can I overload template functions in a way so that the compiler chooses the fitting template function based on whether the class has functionA, functionB or member? Currently I get errors because I define the same template function multiple times...

template<class TypeWithFunctionA>
int doSomething(const TypeWithFunctionA & h)
{
  return h.functionA();
}

template<class TypeWithFunctionB>
int doSomething(const TypeWithFunctionB & h)
{
  return h.functionB();
}

template<class TypeWithMember>
int doSomething(const TypeWithMember & h)
{
  return h.member;
}
2 Answers

You can overload them with SFINAE. e.g.

template<class TypeWithFunctionA>
auto doSomething(const TypeWithFunctionA & h) -> decltype(h.functionA())
{
  return h.functionA();
}

template<class TypeWithFunctionB>
auto doSomething(const TypeWithFunctionB & h) -> decltype(h.functionB())
{
  return h.functionB();
}

template<class TypeWithMember>
auto doSomething(const TypeWithMember & h) -> decltype(h.member)
{
  return h.member;
}

C++20 makes this very straignforward:

template <class TypeWithFunctionA>
int doSomething(const TypeWithFunctionA &h)
requires requires{h.functionA();}
{
    return h.functionA();
}

template <class TypeWithFunctionB>
int doSomething(const TypeWithFunctionB &h)
requires requires{h.functionB();}
{
    return h.functionB();
}

template <class TypeWithMember>
int doSomething(const TypeWithMember &h)
requires requires{h.member;}
{
    return h.member;
}
Related