gpt4 book ai didi

c++ - 具有模板化返回值解决方法的虚拟模板函数

转载 作者:行者123 更新时间:2023-11-28 05:34:27 24 4
gpt4 key购买 nike

关于必须是虚拟的模板化函数的解决方法的问题在这里很常见,尽管我找不到任何可以帮助解决我的问题的东西,这是这个问题的一个简单变体:need a virtual template member workaround

建议的方法是使用类型删除,从而获得非常干净和简单的解决方案。但是,如果我需要从 visit() 方法返回一个值怎么办? OP 在他的问题中已经有这方面的内容,但由于他从未使用过结果,因此在解决方案中被忽略了。

现在想象一下这段代码:

template <typename T>
class BaseVisitor {
public:
BaseVisitor();
T visit(BaseVisited *visited);
virtual ~BaseVisitor();
}


class BaseVisited {
BaseVisited();
template <typename T>
virtual T accept(BaseVisitor<T> *visitor) { return visitor->visit(this); };
virtual ~BaseVisited();
}

我们仍然需要 accept() 进行模板化,即使在应用了类型删除技巧之后。还有其他想法吗?

注意:我不能使用基类作为返回值,正如在 SO 上的一些答案中所建议的那样,因为 T 也可以代表任何基类型(int、string 等)。

最佳答案

你基本上有两个选择:

  1. accept() 提供通用的返回类型,例如std::any或其前身boost::any .或者,如果您有一些有限数量的可能返回类型,std::variant/boost::variant。这样,成员函数就不需要是模板了——但调用者必须知道如何使用它。

  2. 将输入的结果存储在 Visitor 对象中。您必须存储它而不是返回它,但至少您可以保留类型。您可以使用 Visitor Pattern 处理此问题.我们可以让不同的访问者有不同的结果类型;他们只是将它们存储在内部:

    // a void visitor
    struct ShapePrinter : IShapeVisitor
    {
    void visit(const Square&) override { std::cout << "Square"; }
    void visit(const Circle&) override { std::cout << "Circle"; }
    };

    // a double visitor
    struct ShapePerimeterComputer : IShapeVisitor
    {
    void visit(const Square& square) override { perimeter = 4. * square.sideLength; }
    void visit(const Circle& circle) override { perimeter = 2. * M_PI * circle.radius; }

    double perimeter = 0.;
    };

关于c++ - 具有模板化返回值解决方法的虚拟模板函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38660469/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com