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 );
在这种情况下,65
(int
)转换为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
。这就是它起作用的原因。