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。我希望有人可以为我解决这个问题。
答案 0 :(得分:6)
由于这个构造函数的第二次和第三次工作:
basic_string( std::initializer_list<CharT> init,
const Allocator& alloc = Allocator() );
也就是说,只要编译器看到花括号,就会将{...}
转换为std::initializer_list<T>
以获得合适的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
类型。
希望有所帮助。
答案 1 :(得分:3)
(std::string){65, 66}
是C99复合文字,而不是有效的C ++。一些C ++编译器支持它作为扩展,但他们都应该抱怨充分迂腐的设置。
std::string{65, 66}
(或只是std::string{65}
)有效,因为它们使用std::string
构造函数构建临时initializer_list<char>
。
std::string
没有构造函数采用整数(或char
),因此您的演员阵容无效。
此外,A += 65;
也有效,因为string
有一个operator+=
超载char
。 (不幸的是,这也意味着A += 3.1415926;
&#34;也可以起作用。)
同样地,A += {65, 66};
也会有效,因为string
有operator+=
超载initializer_list<char>
。
答案 2 :(得分:3)
表达式(std::string)65
是演员,即您正在尝试将数字65
转换为std::string
。您的第一个示例无法正常工作,因为int
无法转换为std::string
,因为std::string
没有任何带整数的构造函数。
您的第二个和第三个示例工作,因为A+= (std::string){65}
表示&#34;通过其初始化列表构造函数(第9 here)构造一个临时字符串,并将其附加到A
& #34 ;.请注意,您可以只编写A+= {65}
,并且不会构建临时文件,因为您在初始化程序列表中直接调用std::string::operator+=
,否。 4 here。
答案 3 :(得分:1)
第一个尝试将65
重新解释为std::string
这是不可能的,因为整数与std::string
完全无关。
第二个构造std::string
的实例,将65
传递给它的构造函数。
第二个有效,因为它不是演员。
如果丢弃不必要的括号,它就会变得更清楚,它不是演员表 - 它等同于
A += std::string{65};
和
A += std::string('A');
答案 4 :(得分:1)
在第一种情况下,你使用的是C风格的演员表,你并没有构建std::string
只是试图强迫65成为std::string
。
使用花括号进行初始化会调用initializer_list
ctor,因此在第二个和第三个示例中,您实际构建的是std::string
。这就是它起作用的原因。