No, there isn't. Template default arguments are just that, defaults. Any user could call caster<short, short>
, which would match both overloads.
However, it would be possible to add more dummy arguments.
template <typename T,
typename R = typename std::enable_if<sizeof(unsigned char) == sizeof(T), unsigned char>::type >
R caster(T value) { return reinterpret_cast<R&>(value); }
template <typename T,
typename R = typename std::enable_if<sizeof(short) == sizeof(T), short>::type,
typename = void>
R caster(T value) { return reinterpret_cast<R&>(value); }
(Also note the added typename
.)
However, since all bodies are identical, I probably wouldn't go with overloads.
template <std::size_t N>
struct cast_result;
template <>
struct cast_result<sizeof(std::uint8_t)> {
typedef std::uint8_t type;
};
template <>
struct cast_result<sizeof(std::uint16_t)> {
typedef std::uint16_t type;
};
...
template <typename T, typename R = typename cast_result<sizeof(T)>::type>
R caster(T value) {
return reinterpret_cast<R&>(value);
}
A final note: this use of reinterpret_cast
is a violation of the aliasing rules. However, that's easily fixed:
template <typename T, typename R = typename cast_result<sizeof(T)>::type>
R caster(T value) {
R result;
std::memcpy(&result, &value, sizeof result);
return result;
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…