`std::string::iterator` 保证不是指向 char 的指针吗?

Sho*_*hoe 5 c++ string containers pointers stl

假设存在指针to 的operator<<on重载,并且标准指定类的概要如下,在 \xc2\xa721.4 中:std::ostreamcharstd::string

\n\n
namespace std {\n  template<class charT, class traits = char_traits<charT>,\n    class Allocator = allocator<charT> >\n  class basic_string {\n  public:\n    [...]\n    typedef implementation-defined iterator;\n    typedef implementation-defined const_iterator; \n    [...]\n  };\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

最后给出一个iterator概念的要求,在 \xc2\xa723.2/4 中:const_iteratorContainer

\n\n

在此输入图像描述

\n\n

一个指向的指针char可以满足他们的要求;我是否正确地理解了它的实现定义了以下代码是否编译?

\n\n
std::string string = "abc";\nstd::cout << begin(string);\n
Run Code Online (Sandbox Code Playgroud)\n\n
\n\n

顺便说一句,GCCClang似乎都不接受它。

\n

sky*_*ing 2

简短回答:不。

长答案:

这可能取决于您在“指向字符的指针”一词中放入的内容。要么它可以被严格解释为形式类型char*,或者类似或更宽松地解释为任何字符所在的内存地址。

我没有看到您提到的重载实际上存在于标准中,但尽管如此,可能还存在其他所需的重载。您作为示例的那个似乎不存在(并且它似乎没有任何其他带有std::string::iteratorvs重载的地方char*),您不能例如输出 astd::string::iterator例如:

std::string s = "abc";
std::string.iterator p = s.begin();

std::cout << p; // fails
Run Code Online (Sandbox Code Playgroud)

由于标准规定方法和函数应该存在,即使我们要求实现实际上不需要按照标准中指示的方式正式定义它们,而只是表现得好像是这样(比较翻译的要求序列)您可能仍然需要区分重载,因为您应该能够获取指向它们的指针(并且您需要能够知道该指针应该具有什么类型)。

例如,如果我们有一个规范,说它的行为应该像 和 一样void foo(long)void foo(int)定义,并且实现实际上只包含void foo(long)它,只要程序只发出函数调用,因为fooShorts 会默默地转换为int,那么它就可以正常工作,但一旦某些程序包含获取指向函数的指针的代码,该函数将失败,因为它将存储指针的类型根本不匹配:

 void foo(long);

 foo(1L); // works fine
 foo(1);  // works probably fine, 1 is converted to long first

 void (*f)(int) = foo;  // this fails as it cant convert void(*)(long) to void(*)int
Run Code Online (Sandbox Code Playgroud)

由此我们可以得出结论,std::string::iterator可能需要不同的形式类型(如果char*vs存在重载std::string::iterator)。请注意,即使char*出现,char const*也是一种不同的类型。

但是,如果您只是通过“指向 char 的指针”仅表示字符内存中的地址(不一定是 type char*),那么它当然可以。人们甚至可能会说,很可能确实如此。