2017-02-24 71 views
0

对于不具名的标题,我真的不知道该怎么称呼我所问的内容。用派生类型重载函数的替代方法

我想实现以下目标:拥有一个基类类型的容器,其中包含派生类型的实例,访问容器并根据所访问的派生对象的类型调用函数重载。在之前的一个问题中,我询问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正确的过载,然而,这并不编译在编译时间,它是未知哪种类型x0x1实际上有。但是有没有一些可以实现这种行为的替代设计?

回答

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_fInt2Type<1>::do_f

+0

不幸的是不适用于我的情况,因为实际上'f'函数有不同的返回类型。 –

+0

@lotolmencre:遗憾的是,您的问题是将这项新要求保密...... –

+0

是的,当我构建最小工作示例时,我没有想到它。 –