【问题标题】:Using visitor pattern without writing too many overloads在不编写太多重载的情况下使用访问者模式
【发布时间】:2022-11-16 21:16:04
【问题描述】:

我有两种数据类型,分别称为DragonVectorUnbiasedDragon,我正在使用访问者模式进行动态类型推断。

我只想将 DragonVector 扩展为 DragonVector,对于 UnbiasedDragon 也是如此。

我有以下用于扩展向量的代码:

template<class T>
class ExtendVisitor{
    public:
    void operator()(DragonVector<T>& vec1, const DragonVector<T>& vec2){
        vec1.extend(vec2);
    }
    void operator()(UnbiasedDragon<T>& vec1, const UnbiasedDragon<T>& vec2){
        vec1.extend(vec2);
    }
    void operator()(auto& vec1, const auto& vec2){
        std::cout<<"wrong class"<<std::endl;
    } 
};

我得到error: 'auto' not allowed in function prototype。我正在使用 C++17。

由于只有两个类,我可以在访问者中为所有组合详尽地编写运算符重载。但是随着班级数量的增加,这似乎是不可行的。

我尝试使用模板作为解决方法

template<class T>
class ExtendVisitor{
    public:
    void operator()(DragonVector<T>& vec1, const DragonVector<T>& vec2){
        vec1.extend(vec2);
    }
    void operator()(UnbiasedDragon<T>& vec1, const UnbiasedDragon<T>& vec2){
        vec1.extend(vec2);
    }
    template<class TT>
    void operator()(TT& vec1, const TT& vec2){
        std::cout<<"wrong class"<<std::endl;
    } 
};

但这也没有成功。

有没有一种方法可以使用访问者模式而不必编写所有可能的组合?

【问题讨论】:

    标签: c++ oop c++17 visitor-pattern


    【解决方案1】:

    您可以将其作为模板来捕获所有其他组合。在您的尝试中,您的方法具有相同类型的两个参数,但您想要不同的类型:

    template <typename A,typename B>
    void operator()(A& vec1, const B& vec2){
        std::cout<<"wrong class"<<std::endl;
    } 
    

    或者使用 lambda,如此处的示例所示:https://en.cppreference.com/w/cpp/utility/variant/visit。自 C++14 以来,通用 lambda 就可用了。

    【讨论】:

      猜你喜欢
      • 2012-03-09
      • 1970-01-01
      • 1970-01-01
      • 2019-05-14
      • 2021-05-06
      • 1970-01-01
      • 2021-03-04
      • 1970-01-01
      • 2022-11-16
      相关资源
      最近更新 更多