#include <functional>
#include <iostream>
#include <type_traits>
#include <utility>
struct Vector3f64 {
double x;
double y;
double z;
};
struct Vector3f32 {
float x;
float y;
float z;
};
// I use this to select their element type in functions:
template <typename T>
using param_vector = std::conditional_t<std::is_same<std::remove_const_t<std::remove_reference_t<T>>, Vector3f64>::value, double, float>;
// This is the function I want to pull the return type from:
template <typename T>
T VectorVolume(const T x, const T y, const T z) {
return x * x + y * y + z * z;
}
template <typename R, typename... ARGS>
R make_func(R(*ptr)(ARGS...));
template <typename T>
decltype(make_func(&VectorVolume<param_vector<T>>)) func(const T& dir) {
return VectorVolume(dir.x, dir.y, dir.z);
}
int main() {
const Vector3f64 foo{ 10.0, 10.0, 10.0 };
std::cout << func(foo) << std::endl;
}
I2luY2x1ZGUgPGZ1bmN0aW9uYWw+CiNpbmNsdWRlIDxpb3N0cmVhbT4KI2luY2x1ZGUgPHR5cGVfdHJhaXRzPgojaW5jbHVkZSA8dXRpbGl0eT4KCnN0cnVjdCBWZWN0b3IzZjY0IHsKICBkb3VibGUgeDsKICBkb3VibGUgeTsKICBkb3VibGUgejsKfTsKCnN0cnVjdCBWZWN0b3IzZjMyIHsKICBmbG9hdCB4OwogIGZsb2F0IHk7CiAgZmxvYXQgejsKfTsKCi8vIEkgdXNlIHRoaXMgdG8gc2VsZWN0IHRoZWlyIGVsZW1lbnQgdHlwZSBpbiBmdW5jdGlvbnM6CnRlbXBsYXRlIDx0eXBlbmFtZSBUPgp1c2luZyBwYXJhbV92ZWN0b3IgPSBzdGQ6OmNvbmRpdGlvbmFsX3Q8c3RkOjppc19zYW1lPHN0ZDo6cmVtb3ZlX2NvbnN0X3Q8c3RkOjpyZW1vdmVfcmVmZXJlbmNlX3Q8VD4+LCBWZWN0b3IzZjY0Pjo6dmFsdWUsIGRvdWJsZSwgZmxvYXQ+OwoKLy8gVGhpcyBpcyB0aGUgZnVuY3Rpb24gSSB3YW50IHRvIHB1bGwgdGhlIHJldHVybiB0eXBlIGZyb206CnRlbXBsYXRlIDx0eXBlbmFtZSBUPgpUIFZlY3RvclZvbHVtZShjb25zdCBUIHgsIGNvbnN0IFQgeSwgY29uc3QgVCB6KSB7CiAgcmV0dXJuIHggKiB4ICsgeSAqIHkgKyB6ICogejsKfQoKdGVtcGxhdGUgPHR5cGVuYW1lIFIsIHR5cGVuYW1lLi4uIEFSR1M+ClIgbWFrZV9mdW5jKFIoKnB0cikoQVJHUy4uLikpOwoKdGVtcGxhdGUgPHR5cGVuYW1lIFQ+CmRlY2x0eXBlKG1ha2VfZnVuYygmVmVjdG9yVm9sdW1lPHBhcmFtX3ZlY3RvcjxUPj4pKSBmdW5jKGNvbnN0IFQmIGRpcikgewogIHJldHVybiBWZWN0b3JWb2x1bWUoZGlyLngsIGRpci55LCBkaXIueik7Cn0KCmludCBtYWluKCkgewogIGNvbnN0IFZlY3RvcjNmNjQgZm9veyAxMC4wLCAxMC4wLCAxMC4wIH07CgogIHN0ZDo6Y291dCA8PCBmdW5jKGZvbykgPDwgc3RkOjplbmRsOwp9