【问题标题】:C++ string - strange behaviour when using initialization list constructorC++ 字符串 - 使用初始化列表构造函数时的奇怪行为
【发布时间】:2016-05-14 01:10:43
【问题描述】:

我知道我可以使用字符数组和初始化列表来填充字符串。

看起来编译器做了一些从 int 到 initializer_list 或 allocator 的隐式提升。但我不知道为什么它没有给我任何警告以及为什么它使它隐含。

你能解释一下字符串 s4 和 s5 会发生什么吗?

http://ideone.com/5Agc2T

#include <iostream>
#include <string>
using namespace std;

class A{
};

int main() {

    // string::string(charT const* s)
    string s1("12345");
    // 5 - because constructor takes into account null-terminated character
    cout << s1.size() << endl;      

    // string(std::initializer_list<charT> ilist)
    string s2({'1','2','3','4','5'});   
    // 5 - because string is built from the contents of the initializer list init.  
    cout << s2.size()<<endl;

    // string::string(charT const* s, size_type count)
    string s3("12345",3);
    // 3 -  Constructs the string with the first count characters of character string pointed to by s
    cout << s3.size() << endl;

    // basic_string( std::initializer_list<CharT> init,const Allocator& alloc = Allocator() ); - ?
    string s4({'1','2','3','4','5'},3);
    // 2 - why this compiles (with no warning) and what this result means?
    cout << s4.size() << endl;



    string s5({'1','2','3','4','5'},5);
    // 0 - why this compiles (with no warning) and what this result means?
    cout << s5.size() << endl;

    // basic_string( std::initializer_list<CharT> init,const Allocator& alloc = Allocator() );
    // doesn't compile, no known conversion for argument 2 from 'A' to 'const std::allocator<char>&'
    //string s6({'1','2','3','4','5'},A());
    //cout << s6.size() << endl;

    return 0;
}

【问题讨论】:

  • 您能向我解释一下您的期望,而不是会发生什么吗?我在这段代码中看不到任何无意的东西。
  • 是的,当然。我期望两个构造函数具有相同的行为,一个也采用字符数组和初始化列表。

标签: c++ string c++11 constructor initializer-list


【解决方案1】:
string s6({'1','2','3','4','5'},3);
string s7({'1','2','3','4','5'},5);

实际上,这些初始化不只是调用std::initializer_list 构造函数。第二个参数不能隐式转换为std::allocator,所以要考虑其他构造函数。调用的构造函数是具有此签名的构造函数:

basic_string( const basic_string& other, 
              size_type pos, 
              size_type count = std::basic_string::npos,
              const Allocator& alloc = Allocator() );

std::initializer_list 构造函数用于从braced-init-list 创建一个临时std::string,以作为other 参数传递给上述构造函数。临时可以绑定到它,因为它是对 const 的引用。因此,第二个参数是 pos 参数,它用作子字符串复制构造的起点。

所以s6是区间[3, 5)中的字符(即"45"),s7是区间[5,5)中的字符(即"")。

【讨论】:

  • 哇。这些陷阱是有时使 C++ 难以获得的一个例子。
  • 我不明白 OP 还期待什么?!
  • 他们希望编译器抱怨没有从 5const std::allocator&lt;char&gt;&amp; 的隐式转换,因为他们只考虑将构造函数作为一个选项。
猜你喜欢
  • 2013-02-15
  • 1970-01-01
  • 2017-03-12
  • 1970-01-01
  • 1970-01-01
  • 2011-09-04
  • 2017-03-07
  • 1970-01-01
  • 2021-12-06
相关资源
最近更新 更多