相关疑难解决方法(0)

我可以取消引用 std::string.end() 吗?

我相信对此的常见反应是“不”,end()因为容器的迭代器表示“过去结束”地址,这是取消引用的未定义行为。我在标准中找不到一个明确的声明来免除字符串的约束,即使字符串比其他容器有特殊情况。

C++11 标准声明您可以读取超过字符串末尾的一个索引。string[size()]引用空终止符的只读值。

24.3.2.5 basic_string 元素访问 [string.access]

const_reference operator[](size_type pos) const;

reference operator[](size_type pos);

(1)要求: pos <= size() .

(2)回报: *(begin() + pos) if pos < size()。否则,返回对类型charT为 value的对象的引用 charT(),其中将对象修改为除charT()导致未定义行为之外的任何值。

front()被定义为等效于return operator[](0)which 等效return operator[](size())于一个空字符串。

end() - begin()被明确定义为字符串长度的差异,因此end()必须指向的索引size()才能定义该算术。

在上面的标准摘录中,它说明这operator[](pos)等效于*(begin() + pos)if pos < size()。它并不是说您可以取消引用begin() + size(),但您认为假设这应该被明确定义是否合理?或者更好的是,您是否知道一些证明可以将字符串迭代器从约束中排除?

另外,能否证明*(begin() + i)for …

c++ string std language-lawyer

9
推荐指数
1
解决办法
313
查看次数

cplusplus.com说std :: string的过去结尾"不能被解除引用"

如果你能为我清除一些困惑,我想要它.我正在编写一个函数来删除字符串中的重复字符,例如"AB - >"AAABB".

void remove_dups(std::string& str) { 
    std::string::iterator it = str.begin();
    while (it != str.end()) {
        if (*(it+1) == *it) {
            str.erase(it+1);
        } else {
            ++it;
        }
    }
} 
Run Code Online (Sandbox Code Playgroud)

它在测试时似乎有效.但是,我想知道,不应该有栅栏问题吗?当'it'是字符串的结尾时,if语句会查看不存在的下一个字符.根据cplusplus.com,

过去的结尾字符是一个理论字符,它将跟随字符串中的最后一个字符.它不应被解除引用.( http://www.cplusplus.com/reference/string/string/end/)

所以我想知道为什么我的函数似乎通过了测试,以及如何以优雅的方式重写整个事情来绕过fencepost问题.(对我来说很容易,伙计.我是一个n00b.)

像它一样重写它

void remove_dups(std::string& str) { 
    std::string::iterator it = str.begin();
    while (it != str.end()) {
        if ((it+1) != str.end() && *(it+1) == *it) {
            str.erase(it+1);
        } else {
            ++it;
        }
    }
} 
Run Code Online (Sandbox Code Playgroud)

似乎不优雅.

c++

5
推荐指数
1
解决办法
355
查看次数

标签 统计

c++ ×2

language-lawyer ×1

std ×1

string ×1