Reputation: 425
I have
template<typename DistanceFunc>
class C
{
using DistanceType = // the return type from DistanceFunc
public:
C(DistanceType distance, DistanceFunc f)
: m_distance(distance),
m_f(f)
{}
private:
DistanceType m_distance;
DistanceFunc m_f;
};
How do I derive the return type from DistanceFunc
for DistanceType
?
Upvotes: 0
Views: 66
Reputation: 66230
How do I derive the return type from DistanceFunc for DistanceType?
Another solution could be use template specialization.
You can declare C
as receiving a typename
, without defining it
template <typename>
class C;
Then you can define a specialization of C receiving a (pointer to) function type as follows
template <typename DistanceType, typename ... Args>
class C<DistanceType(*)(Args...)>
{
using DistanceFunc = DistanceType(*)(Args...);
public:
C(DistanceType distance, DistanceFunc f)
: m_distance(distance), m_f(f)
{}
private:
DistanceType m_distance;
DistanceFunc m_f;
};
As you can see the function type is resolved as a return type and the types of the arguments. Now DistanceType
is simply deduced (as return type) and you have to recreate DistanceFunc
.
You can use it as follows
int foo (int, long)
{ return 0; }
// ...
C<decltype(&foo)> c0{0, &foo};
Starting from C++17 you can also add a deduction guide
template <typename DistanceType, typename ... Args>
C(DistanceType, DistanceType(*)(Args...)) -> C<DistanceType(*)(Args...)>;
so you can declare a C
object simply as
C c0{0, &foo}; // C<decltype(&foo)> is deduced
Upvotes: 2
Reputation: 66230
How do I derive the return type from DistanceFunc for DistanceType?
Depends. How is called a function of type DistanceFunc
?
Suppose is called with an int
, you can try something as
using DistanceType = decltype(std::declval<DistanceFunc>()(std::declval<int>()));
If you have the types received from DistanceFunc
, using decltype()
and std::declval()
you can simulate a call to the function and obtain the resulting type.
Upvotes: 1