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

时间:2015-10-23 02:54:47

标签: c++ string pointers stl containers

鉴于指向operator<<的指针std::ostream上的char重载存在,并且鉴于该标准指定std::string类的概要如下,在§21.4中:

namespace std {
  template<class charT, class traits = char_traits<charT>,
    class Allocator = allocator<charT> >
  class basic_string {
  public:
    [...]
    typedef implementation-defined iterator;
    typedef implementation-defined const_iterator; 
    [...]
  };
}

最后,iterator概念的const_iteratorContainer的要求见§23.2/ 4:

enter image description here

和指向char的指针会满足它们;我是否正确地阅读了它的实现定义了以下代码是否编译?

std::string string = "abc";
std::cout << begin(string);

在旁注中,GCCClang似乎都不接受它。

2 个答案:

答案 0 :(得分:0)

简短回答:不。

答案很长:

这可能取决于你在措辞和#34;指向char&#34;的指针。要么它可以严格地解释为正式类型char*,要么类似于或者更松散地解释为角色所在的内存地址。

我没有看到你提到的超载确实存在于标准中,但是可能还存在其他所需的重载。你所采用的那个似乎并不存在(并且它似乎不是任何其他具有std::string::iterator vs char*重载的地方,你不能输出例如例如std::string::iterator

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

std::cout << p; // fails

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

例如,如果我们有一个规范说它应该表现得好像定义了void foo(long)void foo(int)并且实现实际上只包含void foo(long)那么只要程序可以正常工作只发出函数调用foo,因为short会无声地转换为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

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

但是,如果你只是通过&#34;指向char&#34;只表示一个字符的内存中的地址(不一定是类型char*),它当然可以。人们甚至可以争辩说它可能很有可能。

答案 1 :(得分:0)

std::string迭代器的(实际)类型是实现定义的。不要求它们是指针,也不要求它们不是指针。

也没有要求标准流具有operator<<()的变体,它接受来自任何标准容器(包括std::string)的迭代器。相反,没有要求它不应该。这意味着它是实现定义的,你的帖子末尾的代码是否编译。