I'm making a hooking library, which basically intercepts a function and makes it jump to the intercept function.
class CHook
{
public:
template<typename S, typename D>
void SetupHook(S Source, D Destionation)
{
pSource = (PBYTE)Source;
pDestination = (PBYTE)Destionation;
}
private:
PBYTE pSource;
PBYTE pDestination;
};
I want CHook::SetupHook to take (for Destination) either DWORD (address of function), function pointer which both can be type casted to PBYTE.
I want CHook::SetupHook to also be able to take a function pointer from lambda but it cannot be type casted to PBYTE so I overload it and since I know lambda function are classes I use std::is_class to identify them.
template<typename S, typename D>
void SetupHook(S Source, typename std::enable_if<!std::is_class<D>::value, D>::type Destionation)
{
pSource = (PBYTE)Source;
pDestination = (PBYTE)Destionation;
}
template<typename S, typename D>
void SetupHook(S Source, typename std::enable_if<std::is_class<D>::value, D>::type Destionation)
{
pSource = (PBYTE)Source;
pDestination = (PBYTE)to_function_pointer(Destionation);
}
But it results in these erorrs:
error C2783: 'void CHook::SetupHook(S,std::enable_if<std::is_class<D>::value,D>::type)': could not deduce template argument for 'D'
note: see declaration of 'CHook::SetupHook'
When you write code like:
template <typename S, typename D>
void SetupHook(S Source, typename std::enable_if<!std::is_class<D>::value, D>::type Destionation)
{
// (...)
}
you make D a non-deducible type template parameter. That is, a type template parameter list, <typename S, typename D>, does not correspond to the parameter list of a function, and so, the compiler can't tell which type template parameter it is supposed to deduce in place of
typename std::enable_if<!std::is_class<D>::value, D>::type
Formally, a nested name specifier introduces a non-deduced context.
The solution is let the compiler deduce D, as a plain parameter type, and to put std::enable_if elsewhere, e.g.:
template <typename S, typename D>
typename std::enable_if<!std::is_class<D>::value>::type SetupHook(S Source, D Destionation)
{
// (...)
}
Now, the compiler sees that D is the type of the second argument expression.
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