#include <iostream>
#include <vector>
using namespace std;
enum typeData
{
ValueDouble,
ValueFloat
};
struct data
{
typeData TypeData;
vector<double> getDoubleValues() const { return vector<double>(); }
vector<float> getFloatValues() const { return vector<float>(); }
};
template <typename R, typename F>
R Dispatch(const data& d, F f)
{
switch (d.TypeData)
{
case ValueDouble: return f(d.getDoubleValues());
case ValueFloat: return f(d.getFloatValues());
default: break; // ?
}
}
//usage
int func(const std::vector<double>& v)
{
return v.size();
}
int func(const std::vector<float>& v)
{
return v.size() + 1;
}
template <typename T>
struct D
{
template <typename V>
T operator()(const std::vector<V>& v) const { return func(v); }
};
int main()
{
data d;
d.TypeData = ValueDouble;
int h1 = Dispatch<int>(d, D<int>());
cout << "h1 = " << h1 << endl;
d.TypeData = ValueFloat;
int h2 = Dispatch<int>(d, D<int>());
cout << "h2 = " << h2 << endl;
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dmVjdG9yPgoKdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCmVudW0gdHlwZURhdGEKewoJVmFsdWVEb3VibGUsCglWYWx1ZUZsb2F0Cn07CgpzdHJ1Y3QgZGF0YQp7CiAgICB0eXBlRGF0YSBUeXBlRGF0YTsKICAgIHZlY3Rvcjxkb3VibGU+IGdldERvdWJsZVZhbHVlcygpIGNvbnN0IHsgcmV0dXJuIHZlY3Rvcjxkb3VibGU+KCk7IH0KICAgIHZlY3RvcjxmbG9hdD4gZ2V0RmxvYXRWYWx1ZXMoKSBjb25zdCB7IHJldHVybiB2ZWN0b3I8ZmxvYXQ+KCk7IH0KfTsKCnRlbXBsYXRlIDx0eXBlbmFtZSBSLCB0eXBlbmFtZSBGPgpSIERpc3BhdGNoKGNvbnN0IGRhdGEmIGQsIEYgZikKewogIHN3aXRjaCAoZC5UeXBlRGF0YSkKICB7CiAgIGNhc2UgVmFsdWVEb3VibGU6IHJldHVybiBmKGQuZ2V0RG91YmxlVmFsdWVzKCkpOwogICBjYXNlIFZhbHVlRmxvYXQ6IHJldHVybiBmKGQuZ2V0RmxvYXRWYWx1ZXMoKSk7CiAgIGRlZmF1bHQ6IGJyZWFrOyAvLyA/CiAgfQp9CgovL3VzYWdlCmludCBmdW5jKGNvbnN0IHN0ZDo6dmVjdG9yPGRvdWJsZT4mIHYpCnsKICByZXR1cm4gdi5zaXplKCk7Cn0KCmludCBmdW5jKGNvbnN0IHN0ZDo6dmVjdG9yPGZsb2F0PiYgdikKewogIHJldHVybiB2LnNpemUoKSArIDE7Cn0KCnRlbXBsYXRlIDx0eXBlbmFtZSBUPgpzdHJ1Y3QgRAp7CiAgdGVtcGxhdGUgPHR5cGVuYW1lIFY+CiAgVCBvcGVyYXRvcigpKGNvbnN0IHN0ZDo6dmVjdG9yPFY+JiB2KSBjb25zdCB7IHJldHVybiBmdW5jKHYpOyB9Cn07CgppbnQgbWFpbigpCnsKCWRhdGEgZDsKICAgIGQuVHlwZURhdGEgPSBWYWx1ZURvdWJsZTsKCiAgICBpbnQgaDEgPSBEaXNwYXRjaDxpbnQ+KGQsIEQ8aW50PigpKTsKICAgIGNvdXQgPDwgImgxID0gIiA8PCBoMSA8PCBlbmRsOwogICAgCiAgICBkLlR5cGVEYXRhID0gVmFsdWVGbG9hdDsKICAgIGludCBoMiA9IERpc3BhdGNoPGludD4oZCwgRDxpbnQ+KCkpOwogICAgY291dCA8PCAiaDIgPSAiIDw8IGgyIDw8IGVuZGw7CglyZXR1cm4gMDsKfQ==