【问题标题】:Alternative to overloading functions with derived types使用派生类型重载函数的替代方法
【发布时间】:2017-07-15 23:07:41
【问题描述】:

对不起,标题信息不充分,我真的不知道我在问什么。

我想实现以下目标:拥有一个带有派生类型实例的基类类型容器,访问容器并根据访问的派生对象的类型调用函数重载。在我之前问过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 实际上有哪种类型。但是是否有一些替代设计可以实现这种行为?

【问题讨论】:

    标签: c++ polymorphism derived-class overloading


    【解决方案1】:

    重载是一种基于静态类型的静态机制。

    如果您想根据对象的动态类型动态地改变行为,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&lt;0&gt;::do_fInt2Type&lt;1&gt;::do_f

    【讨论】:

    • 不幸的是不适用于我的情况,因为实际上f-函数具有不同的返回类型。
    • @lotolmencre:很遗憾你的问题是对这个新要求保密......
    • 是的,我在构建最小工作示例时没有想到这一点。
    猜你喜欢
    • 1970-01-01
    • 2014-07-25
    • 1970-01-01
    • 2014-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-30
    • 1970-01-01
    相关资源
    最近更新 更多