#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<class R, class... ARGS>
std::function<R(ARGS...)> make_func(R(*ptr)(ARGS...)) {
return std::function<R(ARGS...)>(ptr);
}
// This function fails to compile:
template <typename T>
typename decltype(make_func(&VectorVolume<param_vector<T>>))::result_type 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+OwoKLy8gVGhpcyBpcyB0aGUgZnVuY3Rpb24gSSB3YW50IHRvIHB1bGwgdGhlIHJldHVybiB0eXBlIGZyb206CnRlbXBsYXRlIDx0eXBlbmFtZSBUPgpUIFZlY3RvclZvbHVtZShjb25zdCBUIHgsIGNvbnN0IFQgeSwgY29uc3QgVCB6KQp7CiAgcmV0dXJuIHggKiB4ICsgeSAqIHkgKyB6ICogejsKfQoKdGVtcGxhdGU8Y2xhc3MgUiwgY2xhc3MuLi4gQVJHUz4Kc3RkOjpmdW5jdGlvbjxSKEFSR1MuLi4pPiBtYWtlX2Z1bmMoUigqcHRyKShBUkdTLi4uKSkgewogIHJldHVybiBzdGQ6OmZ1bmN0aW9uPFIoQVJHUy4uLik+KHB0cik7Cn0KCi8vIFRoaXMgZnVuY3Rpb24gZmFpbHMgdG8gY29tcGlsZToKdGVtcGxhdGUgPHR5cGVuYW1lIFQ+CnR5cGVuYW1lIGRlY2x0eXBlKG1ha2VfZnVuYygmVmVjdG9yVm9sdW1lPHBhcmFtX3ZlY3RvcjxUPj4pKTo6cmVzdWx0X3R5cGUgZnVuYyhjb25zdCBUJiBkaXIpCnsKICByZXR1cm4gVmVjdG9yVm9sdW1lKGRpci54LCBkaXIueSwgZGlyLnopOwp9CgppbnQgbWFpbigpIHsKICBjb25zdCBWZWN0b3IzZjY0IGZvb3sgMTAuMCwgMTAuMCwgMTAuMCB9OwoKICBzdGQ6OmNvdXQgPDwgZnVuYyhmb28pIDw8IHN0ZDo6ZW5kbDsKfQo=