C++ 为什么';tc++;std::set有一个';at';函数和什么是内联选项

C++ 为什么';tc++;std::set有一个';at';函数和什么是内联选项,c++,C++,考虑以下代码 std::map<int, std::string> someMap; [... populate the map ...] class MyClass { public: MyClass(int stringNumber) : mString(someMap.at(stringNumber)) {} private: std::string mString; }; std::map someMap; […填充地图…] 类MyCla

考虑以下代码

std::map<int, std::string> someMap;
[... populate the map ...]

class MyClass
{
public:
    MyClass(int stringNumber)
    : mString(someMap.at(stringNumber))
    {}

private:
    std::string mString;
};
std::map someMap;
[…填充地图…]
类MyClass
{
公众:
MyClass(整数字符串编号)
:mString(someMap.at(stringNumber))
{}
私人:
std::字符串mString;
};
现在假设我想使用这样的类进行重构

struct StringWithID
{
    int stringID;
    std::string stringValue;
}
inline bool operator<(const StringWithID& l, const StringWithID& r) { return l.stringID < r.stringID;}
StringWithID结构
{
int-stringID;
std::字符串字符串值;
}
内联布尔运算符
为什么std::set不能使用“at”函数

如果你已经有了一个值,你想得到什么?这只是一组数字。没有钥匙可以让你查。您要找的是
std::map

我希望它是安全的,扔出去 (而不是UB)如果找不到我的元素。我怎样才能用一个 设置

由于
std::set
不是为您试图实现的目标而设计的,因此您必须使用
std::set::find()
。如果找不到元素,它将返回
std::set::end()。如果您真的需要抛出,只需创建一个helper函数

我不明白你为什么不想使用
std::map

为什么std::set不能使用“at”函数

如果你已经有了一个值,你想得到什么?这只是一组数字。没有钥匙可以让你查。您要找的是
std::map

我希望它是安全的,扔出去 (而不是UB)如果找不到我的元素。我怎样才能用一个 设置

由于
std::set
不是为您试图实现的目标而设计的,因此您必须使用
std::set::find()
。如果找不到元素,它将返回
std::set::end()。如果您真的需要抛出,只需创建一个helper函数


我不明白为什么您不想使用
std::map

映射将键与值关联起来。为您提供对现有键的值的引用,您可以完全修改该键,如果该值不存在,则引发异常

集合
仅保留集合中的密钥。元素是否在集合中。这有点像一个地图,所有的值都是真的,你不能改变这个值。因此,通过构造,它不能具有类似于
的语义

备选方案

  • at()
    最接近的语义是使用,如果键在集合中,则返回1;如果不在集合中,则返回0(值,而不是引用)。如果它的值错误,您可以很容易地抛出。您甚至可以有一个模板函数来为您执行此操作
  • 重构代码以使用
    映射
    而不是集合,并为添加的每个项目使用
    true
    填充映射
    映射将键与值关联起来。为您提供对现有键的值的引用,您可以完全修改该键,如果该值不存在,则引发异常

    集合
    仅保留集合中的密钥。元素是否在集合中。这有点像一个地图,所有的值都是真的,你不能改变这个值。因此,通过构造,它不能具有类似于
    的语义

    备选方案

  • at()
    最接近的语义是使用,如果键在集合中,则返回1;如果不在集合中,则返回0(值,而不是引用)。如果它的值错误,您可以很容易地抛出。您甚至可以有一个模板函数来为您执行此操作
  • 重构代码以使用
    映射
    而不是集合,并为添加的每个项目使用
    true
    填充映射
    这是不可能发生的,因为std::set是一个唯一的有序集。
    at
    对于
    std::set
    来说没有意义。如果要获取集合中与值相等的元素,可以使用
    find
    获取迭代器。find返回迭代器,如果取消引用end iter,则返回UB。这就是将
    at
    添加到其他容器中的全部原因(为检查末端iter并将其丢弃提供速记,因为它是末端iter)。将
    at
    It添加到
    std::set
    给我是非常有意义的。这与将其添加到
    std::map
    中完全一样,实际上并非如此。对于
    std::map
    at
    请求给定键处的元素。既然
    std::set
    只有钥匙,你已经有钥匙了,那么要求它有什么意义呢<代码>标准::设置
  • 不是为您尝试执行的操作而设计的。像以前一样使用
    std::map
    。好的,你说得对。我太傻了。我想我应该删除这个问题。这不可能发生,因为std::set是一个唯一的有序集。
    at
    对于
    std::set
    来说没有意义。如果要获取集合中与值相等的元素,可以使用
    find
    获取迭代器。find返回迭代器,如果取消引用end iter,则返回UB。这就是将
    at
    添加到其他容器中的全部原因(为检查末端iter并将其丢弃提供速记,因为它是末端iter)。将
    at
    It添加到
    std::set
    给我是非常有意义的。这与将其添加到
    std::map
    中完全一样,实际上并非如此。对于
    std::map
    at
    请求给定键处的元素。既然
    std::set
    只有钥匙,你已经有钥匙了,那么要求它有什么意义呢<代码>标准::设置
    不是为您尝试执行的操作而设计的。像以前一样使用
    std::map
    。好的,你说得对。我太傻了。我想我应该删除这个问题。
    std::set<StringWithID> someSet;