ちょっとコストは増えるがこういうのも。

struct Base {
virtual ~Base(){};
virtual void Get() = 0;
}

struct Int : public Base {
int val;
int& Get() { return &val; };
}

struct Double : public Base {
double val;
double& Get() { return &val };
}

main() {
list<Base*> l;
l.push_back(new Int);
l.push_back(new Double);

l[0].Get(); //int& が返る
l[1].Get(); //double& が返る
}