c++ 使用unordered_map时无法解析外部符号

pn9klfpd  于 2023-01-22  发布在  其他
关注(0)|答案(1)|浏览(290)

我试图使用cpp创建一个基本的Python解释器,但我遇到了一个关于_variables容器的未解决的外部符号问题:无序Map
宣言如下:

private:
    static std::unordered_map<std::string, Type*> _variables;//type is a base class for all the types of variables

下面是使用容器的相关代码:

bool Parser::makeAssignment(std::string str)
{
    char ch = '=';
    int count = 0;
    Type* newVar;
    for(int i = 0; (i = str.find(ch, i)) != std::string::npos; i++)
    {
        count++;
    }
    if (count != 1)
    {
        return false;
    }

    std::string::size_type pos = str.find('=');
    std::string varName = str.substr(0, pos);
    std::string varVal = str.substr(pos + 1, str.size());
    Helper::trim(varName);
    Helper::trim(varVal);
    if (!isLegalVarName(varName))
    {
        throw SyntaxException();
    }
    if (getType(varVal) != NULL)
    {
        newVar = getType(varVal);
    }
    else
    {
        throw SyntaxException();
    }//checks if the declaration written is valid

    auto it = _variables.find(varName);
    if (it != _variables.end())
    {
        it->second = newVar;
    }
    else
    {
        _variables.insert({ varName, newVar });
    }
    return true;
}

Type* Parser::getVariableValue(std::string str)
{
    auto it = _variables.find(str);
    if (it != _variables.end())
    {
        return it->second;
    }
    return NULL;
}

void Parser::cleanMemory()
{
    _variables.clear();
}

我也将感谢对这个问题的一般解释(LNK2001),因为我以前遇到过几次。

tmb3ates

tmb3ates1#

这个问题涉及声明定义之间的区别。

声明,例如

class Parser {
...
    static std::unordered_map<std::string, Type*> _variables;
...
};

告诉编译器符号Parser::_variables将可用于给定类型。
所有使用该符号的代码模块(.cpp文件)都将包含带有声明的头文件,以使该模块知道该符号。
在一个地方(仅),符号需要被定义,即示例化,以便它实际上出现在最终的二进制文件中。因此,一个.cpp文件应该有这样的定义:

std::unordered_map<std::string, Type*> Parser::_variables;

简而言之,程序的构建分为两步:编译和链接。
在编译过程中,生成每个代码模块的二进制翻译,除了对使用(声明)但未在该模块中定义的符号(函数和变量)的未解析“外部”引用。
在链接步骤中,所有模块被放在一起,每个模块中未解析的引用通过指向定义它们的模块来解析。如果结果是有一个符号被使用,但没有在任何地方定义,那么该引用仍然未解析,最终的二进制文件无法生成。因此,链接器报告观察到的错误“unresolved external symbol”。

相关问题