C++ - 具有 std::string 的统一初始值设定项

C++ - Uniform initializer with std::string

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

#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的预期效果?

您正在使用 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 附加插图

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.

中提到了这一点

Initially, the candidate functions are the initializer-list constructors ([dcl.init.list]) of the class T and the argument list consists of the initializer list as a single argument.

在您的示例中,第一个参数 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