为什么不能将 int(表示 ASCII 字符)转换为 std::字符串,而没有大括号环绕在 int 周围?


int main() {
    std::string A;
    A += (std::string)65;
    std::cout << A;
}

上面的代码不起作用。它会引发编译器错误。但是下面的代码有效。

int main() {
    std::string A;
    A += (std::string){65};
    std::cout << A;
}

当我用大括号包裹 65 时,它被解释为 ASCII A,就像我希望的那样,但没有大括号,程序就不起作用。我还尝试在大括号中放入多个数字,如下所示:

int main() {
   std::string A;
   A += (std::string){65, 66};
   std::cout << A;
}

那将打印出AB。我只是希望有人能为我澄清这一点。

由于这个构造函数,第二个和第三个工作:

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

也就是说,每当编译器看到大括号时,它都会将{...}转换为合适 T 的std::initializer_list<T>

在您的情况下,它会转换为 std::initializer_list<char>然后传递给上面提到的 std::string 构造函数。

由于存在+=的重载,因此需要std::initializer_list<char>

basic_string& operator+=( std::initializer_list<CharT> ilist );

你可以这样写:

std::string s;
s += {65};
s += {66, 67};

这也应该行得通。

请注意,您也可以编写以下内容:

s += 65;

即使这样也可以工作,但出于不同的原因 - 它将调用以下重载:

basic_string& operator+=( CharT ch );

在这种情况下,65int)转换为char类型。

希望有帮助。

(std::string){65, 66}是 C99 复合文字,不是有效的C++。一些C++编译器支持它作为扩展,但他们都应该抱怨足够迂腐的设置。

std::string{65, 66}(或只是std::string{65})工作,因为它们使用其initializer_list<char>构造函数构造临时std::string

std::string没有采用整数(或char)的构造函数,因此您的强制转换不起作用。

此外,A += 65;也可以工作,因为string有一个超载的operator+= char。(不幸的是,这也意味着A += 3.1415926;也"有效"。

同样,A += {65, 66};也会起作用,因为string有一个超载operator+= initializer_list<char> .

表达式(std::string)65是一个强制转换,即您正在尝试将数字65转换为std::string。你的第一个示例不起作用,因为int不能转换为std::string,因为std::string没有任何接受整数的构造函数。

A+= (std::string){65} 年以来,您的第二个和第三个示例工作意味着"通过其初始值设定项列表构造函数(此处第 9 号)构造一个临时字符串并将其附加到A"。请注意,您可能只是编写了 A+= {65} ,并且不会构造临时,因为您直接在初始值设定项列表中调用std::string::operator+=,此处为 4

第一个试图将65重新解释为std::string
这是不可能的,因为整数和std::string是完全不相关的。

第二个构造std::string的实例,65传递给它的构造函数。

第二个有效,因为它不是演员表。

如果你去掉不必要的括号,它会更清楚地表明它不是演员表 - 它相当于

A += std::string{65};

A += std::string('A');
在第

一种情况下,您使用的是 C 样式转换,您不是在构造一个std::string只是试图强制 65 成为std::string

使用大括号进行初始化会调用initializer_list ctor,因此在第二个和第三个示例中,您实际上是在构造一个std::string。这就是它起作用的原因。

最新更新