c++ - 以自定义类为键的 Unordered_map

标签 c++ compiler-construction unordered-map

我现在正在开发一个编译器,我试图通过从 unordered_map 继承来表示作用域类,因为它本质上是一个符号到声明的哈希表。我向符号添加了自定义哈希函数,但出现错误,提示没有用于初始化 std::pair 的默认构造函数。相关代码如下:

符号.hpp

#pragma once

#include <string>
#include <unordered_set>


class Symbol
{
    friend class Symbol_table;

    Symbol(std::string const* str) : m_str(str) { }
    /// Constructs the symbol from `str`.

public:
    Symbol() : m_str() { }

    std::string const& str() const { return *m_str; }
    /// Returns the spelling of the token.

    friend bool operator==(Symbol a, Symbol b) 
    {
        return a.m_str == b.m_str;
    }

    friend bool operator!=(Symbol a, Symbol b) 
    {
        return a.m_str != b.m_str;
    }

private:
    std::string const* m_str;  
};


class Symbol_table : std::unordered_set<std::string>
{
public:
    Symbol get(std::string const& str);
    /// Returns the unique symbol for `str`.

    Symbol get(char const* str);
    /// Returns the unique symbol for `str`.
};

inline Symbol
Symbol_table::get(std::string const& str)
{
    return &*emplace(str).first;
}

inline Symbol
Symbol_table::get(char const* str)
{
    return &*emplace(str).first;
}


namespace std
{
    template<>
    struct hash<::Symbol>
    {
        std::size_t operator()(::Symbol sym) const noexcept
        {
            std::hash<std::string const*> h;
            return h(&sym.str());
        }
    };
};

作用域.hpp

#pragma once

#include "decl.hpp"
#include "name.hpp"

#include <string>
#include <vector>
#include <unordered_map>

struct Scope : std::unordered_map<Symbol, Decl*>
{
    Decl* lookup(Symbol sym)
    {
        auto iter = find(sym);
        if (iter == end())
        {
            return nullptr;
        }
        return iter->second;
    }

    void declare(Decl* d)
    {
        assert(!already_declared(d));
        emplace(d->get_name()->get_str(), d);
    }

    bool already_declared(Decl* d)
    {
        return d->get_name() != nullptr;
    }
};

struct Scope_stack : std::vector<Scope>
{
    Decl* lookup(Symbol sym)
    {
        for (auto iter = rbegin(); iter != rend(); ++iter)
        {
            if (Decl * d = iter->lookup(sym))
            {
                return d;
            }
        }
        return nullptr;
    }
};

这是编译错误:

/Library/Developer/CommandLineTools/usr/include/c++/v1/memory:1805:31: error: no matching constructor for initialization of
      'std::__1::pair<const Symbol, Decl *>'
            ::new((void*)__p) _Up(_VSTD::forward<_Args>(__args)...);
                              ^   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

我在此 pastebin 中输入的错误下方还有很多内容.

最佳答案

emplace(d->get_name()->get_str(), d);

这里你尝试构造一个std::unordered_map<Symbol, Decl*>::value_type (即 std::pair<Symbol, Decl*> )来自 const std::string&和一个 Decl* .

问题是 Symbol没有采用 std::string 的构造函数, 只有一个 std::string const* .

这是给出提示的错误消息中的行:

/Library/Developer/CommandLineTools/usr/include/c++/v1/utility:422:5: note: candidate constructor not viable: no known conversion from
      'std::__1::basic_string<char>' to 'const const Symbol' for 1st argument
    pair(_T1 const& __t1, _T2 const& __t2)

关于c++ - 以自定义类为键的 Unordered_map,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53765585/

相关文章:

c++ - Qt 5 Qt3D QCircularBuffer 在哪里?

c++ - 用Qt序列化,不用Qt反序列化?

gcc - 自动展开并输出C/C++代码

c++ - 没有opengl的QT项目

c++ - 我不明白 std::tr1::unordered_map

c++ - 如何同时填充 std::unordered_map?

c++ - 使用智能指针释放内存

c++ - 如何修复 arduino ide 中的 "undefined reference to:",尝试使用 googletest

c - 带有 Xcode 4.3.2 的 Mac OS X Lion 上的 Flex 和 Bison

c++ - 有效删除 tr1::unordered_map 中的元素