C++ 中的策略模式和协变 Return 类型

Strategy Pattern and Covariant Return Type in C++

class Context{
public:
    Strategy* strategy;
    void PickStrategy(Strategy *strategy){
        delete this->strategy;
        this->strategy = strategy;
    }

    C* execute(string some_text) const{
        return this->strategy->execute(std::move(some_text));
    }
};
class C{

};

class D: public C{

}
class MyStrategy: public Strategy{
    D* execute(string some_text){
        // business logic
        return pointer_to_D;
    }
}

客户端:

auto context = Context();
context.PickStrategy(new MyStrategy());
auto output1 = context.execute("some_text");
auto output2 = context.execute("some_text2");
if (output1 == output2){
    // business logic
}
bool operator==(const D& d1, const D& d2){
    // business logic
}

我有一个应用程序,我认为采用策略模式非常有意义。所以我决定使用它。但我的问题是,在完全不接触客户端的情况下,我是否可以使用我的重载运算符专门确定特定产品,该产品应该由上下文选择的策略 returned。如您所知,我们允许 return 派生的 class 对象在我们的 C++ 虚拟覆盖函数实现中,这称为协变 return 类型,但自动引用假定最通用的类​​型在这种情况下,在层次结构中导致无法按预期使用重载运算符,尽管我希望它根据上下文中选择的策略在运行时进行更改,而无需进行任何额外的讨厌的整体 dynamic_cast 检查,因为如果我这样做,事实证明使用策略模式是没有意义的。那么,在我的案例中,如何通过上下文对象使用协变 return 类型?

这是一个长期存在的问题。核心问题是,Context 希望对其策略进行动态控制(包括其 return 值的动态类型),但其用户希望对该 return 值进行静态保证。您可以在 return 类型的策略 and/or 上模板 Context,并可能在 return 类型上模板 Strategy,但从根本上说,您需要引入编译时 return 类型的限制,否则您将需要在运行时进行不安全的转换。