Unordered_map 以自定义 class 作为键
Unordered_map with custom class as key
我现在正在开发一个编译器,我试图通过从 unordered_map 继承来表示范围 class,因为它本质上是声明符号的散列 table .我向该符号添加了一个自定义哈希函数,但我收到一条错误消息,抱怨没有用于初始化 std::pair 的默认构造函数。这是相关代码:
Symbol.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());
}
};
};
Scope.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);
在这里,您尝试从 const std::string&
和 Decl*
.
构建 std::unordered_map<Symbol, Decl*>::value_type
(即 std::pair<Symbol, 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)
我现在正在开发一个编译器,我试图通过从 unordered_map 继承来表示范围 class,因为它本质上是声明符号的散列 table .我向该符号添加了一个自定义哈希函数,但我收到一条错误消息,抱怨没有用于初始化 std::pair 的默认构造函数。这是相关代码:
Symbol.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());
}
};
};
Scope.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);
在这里,您尝试从 const std::string&
和 Decl*
.
std::unordered_map<Symbol, Decl*>::value_type
(即 std::pair<Symbol, 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)