When designing a function that adds two values of any distinct classes, I can write the following generically:
template <typename T, typename U>
decltype((*(T*)0) + (*(U*)0)) add(T t, U u) {
return t + u;
}
The interesting part is the return type: decltype((*(T*)0) + (*(U*)0))
. In other words: "The type resulting from the sum of an object of type T
with one of type U
".
But to get an object of type T
, use (*(T*)0)
which, although it is invalid if executed, always results in type T
. Another way to get the same result would be: T() + U()
. The problem is that it is assumed that there is a default constructor for the types, even though I do not even need a constructor for the function.
My question is: is writing this function really allowed and does not create Undefined Behavior?
More generally, can I use expressions that result in Undefined Behavior when executed, but which has a well-defined type, within a decltype
?
Note: In C ++ 11 it is possible to write:
template <typename T, typename U>
auto add(T t, U u) -> decltype(t + u) {
return t + u;
}
And in C ++ 14 you can write:
template <typename T, typename U>
auto add(T t, U u) {
return t + u;
}
But that's not relevant to the question.