对于没有信息的标题,我不知道该怎么称呼我。
我想实现以下目标:拥有一个基类类型的容器,其中包含派生类型的实例,访问容器并根据所访问的派生对象的类型调用函数重载。在之前的一个问题中,我问here我了解到目前为止我想到的静态设计是行不通的。我尝试的方式是:
struct Int2TypeBase{
};
template <int v>
struct Int2Type : public Int2TypeBase
{
enum
{
value = v
};
};
void f(const Int2Type<0>&){
std::cout << "f(const Int2Type<0>&)" << "\n";
}
void f(const Int2Type<1>&){
std::cout << "f(const Int2Type<1>&)" << "\n";
}
int main(){
using namespace std;
std::vector<std::reference_wrapper<Int2TypeBase>> v;
Int2Type<0> i2t_1;
v.emplace_back(i2t_1);
Int2Type<1> i2t_2;
v.emplace_back(i2t_2);
auto x0 = v[0];
auto x1 = v[1];
f(x0.get()); // After my imagination this would have called void f(const Int2Type<0>&)
f(x1.get()); // After my imagination this would have called void f(const Int2Type<1>&)
}
好的,所以我希望选择f
的正确重载,但是这不会在编译时编译,不知道x0
和x1
实际上有哪种类型。但是有一些替代设计可以实现这种行为吗?
答案 0 :(得分:0)
重载是一种基于静态类型的静态机制。
如果要根据对象的动态类型动态更改行为 ,C ++将为此提供另一种内置语言功能:虚拟功能。像这样使用它们:
struct Int2TypeBase
{
virtual void do_f() = 0;
};
template <int v> struct Int2Type : Int2TypeBase
{
void do_f() override
{
// specific behaviour for Int2Type<v> goes here
}
/* ... */
};
void f(Int2TypeBase & x) { x.do_f(); }
现在,您可以在任何基础子对象上调用f
,并在运行时选择正确的行为。特别是,f(x0.get())
和f(x1.get())
现在分别在运行时选择并发送到Int2Type<0>::do_f
和Int2Type<1>::do_f
。