C++ LLVM unique_ptr 问题

C++ LLVM unique_ptr issue

老实说,我不知道该做什么。 当我遇到这个函数时,我正在学习 C++ 的 LLVM 教程(https://llvm.org/docs/tutorial/MyFirstLanguageFrontend/LangImpl02.html):

static std::unique_ptr<ExprAST> ParseNumberExpr() {
  auto Result = std::make_unique<NumberExprAST>(NumVal);
  getNextToken(); // consume the number
  return std::move(Result);
}

它在函数的最后一行给我一个错误,我无法将 unique_ptr<NumberExprAST> 转换为 unique_ptr<ExprAST>(NumberExprAST 是 ExprAST 的子项),我猜这个错误造成有道理,但是这在教程中是怎么回事呢?我逐字逐句地复制了函数(我什至几乎逐字逐句地复制了 类),但我仍然遇到错误。如果其他人已经完成本教程,他们在这种情况下做了什么?

编辑:我被要求显示 AST 文件的完整代码,所以这里是:

#include <string>
#include <vector>
#include <memory>
#include "lexer.hpp"

class ExprAST
{
public:
    virtual ~ExprAST() {}
};

class NumExprAST : ExprAST
{
private:
    double m_val;
public:
    NumExprAST(const double val) {m_val = val;}
};

class VarExprAST : ExprAST
{
private:
    std::string m_name;
public:
    VarExprAST(const std::string &name) {m_name = name;}
};

class BinOprExprAST : ExprAST
{
private:
    char m_opr;
    std::unique_ptr<ExprAST> m_lhs, m_rhs;
public:
    BinOprExprAST(char opr, std::unique_ptr<ExprAST> lhs,
                  std::unique_ptr<ExprAST> rhs)
    {
        m_opr = opr;
        m_lhs = std::move(lhs);
        m_rhs = std::move(rhs);
    }
};

class CallExprAST : public ExprAST {
private:
  std::string m_callee;
  std::vector<std::unique_ptr<ExprAST>> m_args;
public:
    CallExprAST(const std::string &callee,
                std::vector<std::unique_ptr<ExprAST>> args)
    {
        m_callee = callee;
        m_args = args;
    }
};

class PrototypeAST {
    std::string m_name;
    std::vector<std::string> m_args;

public:
    PrototypeAST(const std::string &name, std::vector<std::string> args)
    {
        m_name = name;
        m_args = args;
    }

    const std::string &getName() const {return m_name;}
};

class FunctionAST {
    std::unique_ptr<PrototypeAST> m_proto;
    std::unique_ptr<ExprAST> m_body;

public:
    FunctionAST(std::unique_ptr<PrototypeAST> proto,
                std::unique_ptr<ExprAST> body)
    {
        m_proto = std::move(proto);
        m_body = std::move(body);
    }
};

static int currTok;
static int getNextToken() {return currTok = getToken();}

std::unique_ptr<ExprAST> logErr(const std::string errStr)
{
    std::cerr << "log error: " << errStr << "\n";
    return nullptr;
}
std::unique_ptr<PrototypeAST> logErrP(const std::string errStr)
{
    logErr(errStr);
    return nullptr;
}

static std::unique_ptr<ExprAST> parseNumExpr()
{
    auto result = std::make_unique<NumExprAST>(g_numVal);
    getNextToken();
    return std::move(result);
}

我收到的错误消息是这样的:

no suitable user-defined conversion from "std::unique_ptr<NumExprAST, std::default_delete<NumExprAST>>" to "std::unique_ptr<ExprAST, std::default_delete<ExprAST>>" exists

错误消息来自 VSCode 而不是终端,因此它可能与标准 C++ 错误消息不完全相同。

如果您使用 private inheritance(如 class A:B{}struct A: private B{}),那么您只能在类型本身或友好函数或类型。

因此,如果您希望 unique_ptr 能够进行转换,最简单的方法是使用 public 继承,例如

class NumExprAST : public ExprAST {
   // ...
}