【问题标题】:C++ - Uniform initializer with std::stringC++ - 带有 std::string 的统一初始化器
【发布时间】:2016-08-06 22:25:00
【问题描述】:

我正在尝试使用 C++ 字符串类的统一初始化程序。下面是代码:

#include <iostream>
#include <string>

using namespace std;

int main()
{
    string str1 {"aaaaa"};
    string str2 {5, 'a'};
    string str3 (5, 'a');

    cout << "str1: " << str1 << endl;
    cout << "str2: " << str2 << endl;
    cout << "str3: " << str3 << endl;

    return 0;
}

输出将是:

str1: aaaaa
str2: a
str3: aaaaa

这让我摸不着头脑。为什么str2 无法达到str3 的预期结果?

【问题讨论】:

  • “统一”初始化...

标签: c++ string c++11 uniform-initialization list-initialization


【解决方案1】:

std::string 有一个接受 initializer_list 参数的构造函数。

basic_string( std::initializer_list<CharT> init,
              const Allocator& alloc = Allocator() );

当您使用 braced-init-list 构造 std::string 时,该构造函数总是优先。仅当 braced-init-list 中的元素不能转换为 initializer_list 中的元素类型时才考虑其他构造函数。 [over.match.list]/1 中提到了这一点。

最初,候选函数是类 T 的初始化列表构造函数 ([dcl.init.list]),参数列表由初始化列表作为单个参数组成。

在您的示例中,第一个参数 5 可以隐式转换为 char,因此 initializer_list 构造函数是可行的,并且会被选中。

如果将字符串中的每个字符打印为ints,这一点很明显

void print(char const *prefix, string& s)
{
    cout << prefix << s << ", size " << s.size() << ": ";
    for(int c : s) cout << c << ' ';
    cout << '\n';
}

string str1 {"aaaaa"};
string str2 {5, 'a'};
string str3 (5, 'a');

print("str1: ", str1);
print("str2: ", str2);
print("str3: ", str3);

输出:

str1: aaaaa, size 5: 97 97 97 97 97 
str2: a, size 2: 5 97 
str3: aaaaa, size 5: 97 97 97 97 97 

Live demo

【讨论】:

  • 谢谢。有点明白这里发生了什么。我一直更喜欢统一初始化,因为有人告诉我这是从现在开始的最佳实践(我还是 C++ 新手)。看来我以后要小心了。
  • @Hilman 正如您所发现的,它并不总是如此一致。以vector&lt;int&gt; 为例,vector&lt;int&gt; v1{4,2}, v2(4,2);。这里v1包含2个整数,4和2,而v2包含4个整数,每个都初始化为2。
【解决方案2】:

您正在使用带有此签名的std::string's constructor

std::basic_string( std::initializer_list<CharT> init, const Allocator& alloc = Allocator() );

并且编译器将5 视为char 类型,它转换为不在屏幕上打印的ASCII 类型。如果您将 5 更改为可打印的值,例如 A,其 ASCII 值为 65

string str2 {65, 'a'};

它会打印出来:

Aa

查看 Live on Coliru 并附上插图

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多