The actual function bar is supposed to read from file, where data is written in exactly 4 bytes or 8 bytes (unsigned int - DWORD or DWORD64)
void bar(DWORD64&);
void bar(DWORD&);
template<typename IntType>
void foo(IntType& out)
{
bar(out);
}
int main()
{
int a;
foo(a); // Caller doesn't care
}
Since the caller can pass any integer type (int, LONG, DWORD, LONGLONG or anything) - I want a technique so that foo may make a call to 32-bit bar or 64-bit bar.
In short, it would be like:
template<typename IntType>
void foo(IntType& out)
{
if(sizeof(out)==sizeof(DWORD)) // 32-bit
{
DWORD data;
bar(data); // call DWORD version
out = (IntType)data; // Ignore truncation etc.
}
else
{
DWORD64 data;
bar(data); // call DWORD64 version
out = (IntType)data; // Ignore truncation etc.
}
}
Obviously, I want the "if" part to be resolved at compile time. std::enable_if or something?
Soltuion 1: SFINAE and std::enable_if:
template<typename IntType, typename std::enable_if<sizeof(IntType) == 4>::type* = nullptr>
void foo(IntType& out)
{
DWORD arg = out;
bar(arg);
out = arg;
}
template<typename IntType, typename std::enable_if<sizeof(IntType) == 8>::type* = nullptr>
void foo(IntType& out)
{
DWORD64 arg = out;
bar(arg);
out = arg;
}
Soltuion 2: Delegate-to-class and partial specialisation:
template<typename IntType>
void foo(IntType& out)
{
foo_helper<IntType>::call(out);
}
template <class IntType, std::size_t Size = sizeof(IntType)>
struct foo_helper;
template <class IntType>
struct foo_helper<IntType, 4>
{
static void call(IntType &out)
{
DWORD arg = out;
bar(arg);
out = arg;
}
};
template <class IntType>
struct foo_helper<IntType, 8>
{
static void call(IntType &out)
{
DWORD64 arg = out;
bar(arg);
out = arg;
}
};
Both solutions can be flavoured with static_cast added to taste, particularly around assignment to/from arg.
You could use std::conditional to only differ for sizeof(DWORD) and sizeof(DWORD64) (since you want to support more than just those 2 types):
template<typename IntType>
void foo(IntType& out)
{
typedef typename std::conditional<sizeof(IntType) == sizeof(DWORD), DWORD, DWORD64>::type RetType;
RetType data;
bar(data);
out = static_cast<IntType>(data);
}
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