std::map at 函数总是抛出异常
std::map at function always throwing exception
我有一个基本函数来检查单词是否是键。问题是我的 try catch 块总是捕获out_of_range异常,即使密钥存在也是如此。此问题仅发生在我的 isExclusion 函数中。如果我使用静态字符串在 isExclusion 函数外部检查,那么 at 将不会引发异常。
另外,是否有更好或更有效的方法来检查密钥是否存在?我宁愿不必遍历键列表。
#ifndef TITLES_H_
#define TITLES_H_
#include <algorithm>
#include <string>
#include <vector>
#include <map>
static std::map<std::string, int> exclusions;
static std::vector<std::string> titles;
bool isExclusion(std::string word);
#endif
#include "titles.h"
#include <iostream>
bool isExclusion(std::string word)
{
try
{
exclusions.at(word);
}
catch (std::out_of_range e)
{
return false;
}
return true;
}
#include <iostream>
#include "titles.h"
int main()
{
exclusions["is"] = 1;
exclusions["the"] = 1;
exclusions["of"] = 1;
exclusions["and"] = 1;
exclusions["a"] = 1;
exclusions["but"] = 1;
exclusions["as"] = 1;
titles.push_back("Descent of Man");
titles.push_back("The Ascent of Man");
titles.push_back("The Old Man and The Sea");
titles.push_back("A Portrait of the Artist As a Young Man");
titles.push_back("A Man is a Man but Bubblesort IS A DOG");
std::sort(titles.begin(), titles.end());
try
{
exclusions.at("the");
}
catch(std::out_of_range e)
{
std::cout << "Not foundn";
}
std::cout << "Exclusion?: " << isExclusion("hello") << std::endl;
std::cout << "Exclusion?: " << isExclusion("the") << std::endl;
for(auto i = titles.begin(); i != titles.end(); i++)
{
std::cout << *i << "n";
}
return 0;
}
static std::map<std::string, int> exclusions;
exclusions
定义static
.static
全局变量的范围仅限于其各自的编译单元。这样,就可以在多个编译单元中重用名称。
您可以在两个编译单元中包括每个#include "titles.h"
的此行。因此,您实际上创建了两个具有相同名称的映射,每个映射都仅限于其编译单元。
这些行在main
exclusions["is"] = 1;
exclusions["the"] = 1;
exclusions["of"] = 1;
exclusions["and"] = 1;
exclusions["a"] = 1;
exclusions["but"] = 1;
exclusions["as"] = 1;
因此在与函数不同的映射上运行
bool isExclusion(std::string word)
{
try
{
exclusions.at(word);
}
catch (std::out_of_range e)
{
return false;
}
return true;
}
在另一个单元。 第二个单元中的exclusions
实际上总是空的。
您需要删除static
关键字并将定义移动到其中一个单元(最佳main
)。要在另一个单元中也使用该变量,您必须将其声明为extern
:
extern std::map<std::string, int> exclusions;
但是,最好根本不使用全局变量,而是将映射和单词向量的引用传递给函数。当您使用它时,还可以使它们成为常量引用。(该函数不会修改它们。
bool isExclusion(const std::map<std::string, int>& exclusions, const std::string& word)
你的问题出在以下行上:
static std::map<std::string, int> exclusions;
通过定义这个变量static
,您将在两个单独的翻译单元中创建两个单独的map
。main()
正在使用一种map
,titles.cpp
正在使用另一种。 相反,像这样声明变量:
extern std::map<std::string, int> exclusions;
。,然后将此行添加到titles.cpp
文件中:
std::map<std::string, int> exclusions;
这将导致全局变量对所有翻译单元可见,并且只有一个实际映射。
通常,在头文件中使用static
关键字是一个坏主意(声明类变量的struct
或class
除外)。 有一些例外,但它们是库作者通常担心的深奥场景。
来回答这个问题: 是否有更好或更有效的方法来检查密钥是否存在?
这样做:
if (exclusions.find(word) != exclusions.end())
{
// no, it does not exist
}
else
{
// yes, you found it, use
// exclusions.at(word)
// safely
}
实际上,如果我没记错的话,如果您在元素不存在时只使用"exclusions.at(word)",它会为此键创建一个空元素。
- 从构造函数抛出异常时如何克服内存泄漏
- 函数如何通知用户它基于函数原型抛出异常?
- 在缺少函数重载时抛出异常,并带有 std::variant 而不是编译时错误
- VisualStudios 会抛出异常,而代码块不会 [C++]
- 如果不包含 pthread,为什么 GCC 的线程标准库实现会抛出异常?
- ZMQ::send() 抛出异常并终止 QNX 进程.为什么以及如何从中恢复?
- new(std::nothrow) int[n] 抛出异常
- 为什么g_object_set抛出异常(vcruntime140.dll)?
- 你能防止 std::regex 在无效表达式上抛出异常吗?
- C++子线程抛出异常
- 我们应该在抛出异常之前取消分配内存吗
- 有没有一种方法可以让OpenCLC++绑定为所有错误抛出异常
- 为什么访问模板化变体作为返回值抛出异常
- 如何实现,错误分配中止而不是抛出异常
- std::p riority_queue::p op什么时候会抛出异常
- 在0x5914F3BE抛出异常(基于.dll)
- std::vector 默认构造函数可以抛出异常吗?
- 挂钩创建文件抛出异常:读取访问冲突
- getaddrinfo 抛出异常
- std::map at 函数总是抛出异常