为什么不能将一个 int(代表一个 ASCII 字符)转换为一个 std::string,而不用花括号将 int 包裹起来?
Why isn't it possible to cast an int (representing an ASCII character) to an std::string without curly braces wrapped around the 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() );
也就是说,每当编译器看到大括号时,它都会将 {...}
转换为 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
类型。
希望对您有所帮助。
第一个尝试将 65
重新解释为 std::string
。
这是不可能的,因为整数和 std::string
完全无关。
第二个构造 std::string
的实例,将 65
传递给它的构造函数。
第二个有效,因为它不是演员表。
如果你去掉不必要的括号,就会更清楚它不是强制转换 - 它等同于
A += std::string{65};
然后到
A += std::string('A');
(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;
"works" 也是。)
同样,A += {65, 66};
也可以工作,因为 string
有一个超载的 operator+=
接受 initializer_list<char>
.
在第一种情况下,您使用的是 C 风格的转换,您并不是在构建 std::string
只是试图强制 65 成为 std::string
。
使用大括号进行初始化会调用 initializer_list
构造函数,因此在第二个和第三个示例中,您实际上是在构建 std::string
。这就是它起作用的原因。
表达式 (std::string)65
是一个转换,即您试图将数字 65
转换为 std::string
。您的第一个示例不起作用,因为 int
不能转换为 std::string
,因为 std::string
没有任何采用整数的构造函数。
你的第二个和第三个例子工作因为 A+= (std::string){65}
意味着“通过它的初始化列表构造函数构造一个临时字符串(第 9 here) and append it to A
". Note that you could've just written A+= {65}
, and no temporary will be constructed, since you invoke directly std::string::operator+=
on a initializer list, no. 4 here.
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() );
也就是说,每当编译器看到大括号时,它都会将 {...}
转换为 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
类型。
希望对您有所帮助。
第一个尝试将 65
重新解释为 std::string
。
这是不可能的,因为整数和 std::string
完全无关。
第二个构造 std::string
的实例,将 65
传递给它的构造函数。
第二个有效,因为它不是演员表。
如果你去掉不必要的括号,就会更清楚它不是强制转换 - 它等同于
A += std::string{65};
然后到
A += std::string('A');
(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;
"works" 也是。)
同样,A += {65, 66};
也可以工作,因为 string
有一个超载的 operator+=
接受 initializer_list<char>
.
在第一种情况下,您使用的是 C 风格的转换,您并不是在构建 std::string
只是试图强制 65 成为 std::string
。
使用大括号进行初始化会调用 initializer_list
构造函数,因此在第二个和第三个示例中,您实际上是在构建 std::string
。这就是它起作用的原因。
表达式 (std::string)65
是一个转换,即您试图将数字 65
转换为 std::string
。您的第一个示例不起作用,因为 int
不能转换为 std::string
,因为 std::string
没有任何采用整数的构造函数。
你的第二个和第三个例子工作因为 A+= (std::string){65}
意味着“通过它的初始化列表构造函数构造一个临时字符串(第 9 here) and append it to A
". Note that you could've just written A+= {65}
, and no temporary will be constructed, since you invoke directly std::string::operator+=
on a initializer list, no. 4 here.