我正在从数据库加载各种数据,并且已经实现了模板方法:
template <typename R>
bool
loadMap(map<const string, R> &store, const char *query) {
{
...
for (auto row : rows(query)) {
store.insert(make_pair(row[0], R(row[1], row[2], ....));
}
}
该方法将查询
发送到数据库服务器,并用结果填充存储
。第一列成为映射的键,其余字段形成值结构。这有效。
但是,在某些情况下,查询仅返回一个列 - 该列存储在set
(或unordered_set
)中-- 没有任何与之相关的值。
目前这些情况是通过它们自己的方法处理的,我想将我的 loadMap
函数扩展到这些其他类型的容器 - 也许将其重命名为 loadContainer
.
这个新的 loadContainer
声明看起来如何,以及它如何仅使用键而不使用值调用 store.insert()
?
(我知道将集合转换为所有值为空的 map 的做法,但我想避免这种情况。)
实际上,我什至想不出一种方法来处理 map
和 unordered_map
——尽管 insert
是完全相同的,但是如何我会声明这样一个函数吗?这两种 map 类型似乎没有共同的祖先(也没有“接口(interface)”,用 Java 术语来说)...
最佳答案
您可能有重载
template <typename R>
bool loadContainer(std::map<string, R> &store, const char *query) {
{
// ...
for (auto row : rows(query)) {
store.insert(std::make_pair(row[0], R(row[1], row[2] /*, ...*/));
}
// ...
}
bool loadContainer(std::set<string> &store, const char *query) {
{
// ...
for (auto row : rows(query)) {
store.insert(row[0]);
}
// ...
}
或者,为了避免过载,您可以这样做 (C++17)
template <typename Container>
bool loadContainer(Container& store, const char *query) {
{
// ...
for (auto row : rows(query)) {
if constexpr (is_map<Container>::value) {
using R = typename Container::mapped_type;
store.insert(std::make_pair(row[0], R(row[1], row[2] /*, ...*/));
} else {
store.insert(row[0]);
}
}
// ...
}
具有适当的特征,例如
template <typename T, typename Enabler = void>
struct is_map : std::false_type {};
template <typename T>
struct is_map<T, std::void_t<typename T::mapped_type>> : std::true_type {};
关于c++ - 如何实现 map 和集合通用的模板?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65414765/