将字符推送到字符串向量时出现意外行为
Unexpected behavior when pushing a character to vector of strings
我试图通过先将字符转换为字符串来将字符插入到字符串向量中,但情况 1 不起作用,但情况 2 有效。有人可以解释这种行为吗?有没有将 char 直接插入 vector 的解决方法?
// vector of strings
vector lt; std::string gt; out;
// EDIT - stack overflow is not letting me post "less than" sign so using lt; and gt; instead
// a character
char ch;
// assign some value to ch and push to vector
// CASE 1: don't work
out.push_back("" + ch);
// CASE 2: works
string str = "";
out.push_back(str + ch);
PS - 我正在使用 C++14
此代码编译并工作:
#include <iostream>
#include <vector>
#include <string>
using namespace std;
int main() {
// vector of strings
vector<string> out;
// a character
char ch;
// assign some value to ch and push to vector
// Case 0: works because a const char * can be coerced into a string
out.push_back("");
// Case 1: Does not work
// you can't add a const char * and a char.
// Some compilers coerce the char into an int and add that to the pointer
// producing undefined behavior (access to un-allocated memory)
// out.push_back("" + ' ');
// CASE 1a: Works, but I'm 'cheating' by
// explicitly constructing a string.
out.push_back(string("") + ch);
// Case 1b: Works using a different string constructor
// This is probably the best approach:
out.push_back(string(1, ' '));
// CASE 2: works
string str = "";
out.push_back(str + ch);
std::cout << "out contains " << out.size() << " entries" << std::endl;
return 0;
}
结果:
out contains 3 entries
术语 ""
不代表 std::string
实例,而是 const char*
文字,因此当您向其添加 ch
时,您正在执行指针运算并且可能会收到一条编译器警告:
warning: array subscript is above array bounds
到 push_back
一个 char
作为一个 std::string
到一个 std::vector<std::string>
只需做:
std::vector<std::string> vec;
char ch = 'a';
vec.push_back(std::string()+ch); // construct empty std::string, add ch, push_back
您的代码有问题。
这是类型特征,可帮助您检查名称是否为模板化类型:
/***Check if type is simple template***/
template <template<class...> class>
constexpr bool is_template_type()
{ return true; }
template <class>
constexpr bool is_template_type()
{ return false; }
有了这个,您可以检查 vector
是否是创建变量的有效类型。所以:
static_assert(!is_template_type<vector>(),
"vector is not valid type for creating a variable");
导致编译失败,因为无法创建class template
的变量。您必须指定 TYPE
,std::vector
应该存储。你的问题标题是:
vector of strings
所以您应该创建 std::vector<std::string>
变量。
您的代码的另一个问题是:
"" + ch
。
你认为它有什么作用? ""
类型为char const[1]
,ch
类型为char
。 char const[1]
可隐式转换为 char const *
,并且由于您可以将整数值添加到指针 - 它可以编译。但这不是你想要的!
这是你的 ""
记忆:
`[=12=]' ? ? ? ? ? ? ...
/\
将 ch
添加到 ""
后,结果如下:
//ch is 5 for example
`[=13=]' ? ? ? ? ? ? ...
/\
所以你用一些未指定的地址创建了 std::string
。实际上,访问数组 out-of-bounds 是 C++ 中的未定义行为。
您应该使用 std::string() + ch
或用户 W.F 的字符串文字语法。发表在他对你的问题的评论中。
另外不要忘记初始化ch
,因为使用未指定的值也是未定义的行为。
我试图通过先将字符转换为字符串来将字符插入到字符串向量中,但情况 1 不起作用,但情况 2 有效。有人可以解释这种行为吗?有没有将 char 直接插入 vector 的解决方法?
// vector of strings
vector lt; std::string gt; out;
// EDIT - stack overflow is not letting me post "less than" sign so using lt; and gt; instead
// a character
char ch;
// assign some value to ch and push to vector
// CASE 1: don't work
out.push_back("" + ch);
// CASE 2: works
string str = "";
out.push_back(str + ch);
PS - 我正在使用 C++14
此代码编译并工作:
#include <iostream>
#include <vector>
#include <string>
using namespace std;
int main() {
// vector of strings
vector<string> out;
// a character
char ch;
// assign some value to ch and push to vector
// Case 0: works because a const char * can be coerced into a string
out.push_back("");
// Case 1: Does not work
// you can't add a const char * and a char.
// Some compilers coerce the char into an int and add that to the pointer
// producing undefined behavior (access to un-allocated memory)
// out.push_back("" + ' ');
// CASE 1a: Works, but I'm 'cheating' by
// explicitly constructing a string.
out.push_back(string("") + ch);
// Case 1b: Works using a different string constructor
// This is probably the best approach:
out.push_back(string(1, ' '));
// CASE 2: works
string str = "";
out.push_back(str + ch);
std::cout << "out contains " << out.size() << " entries" << std::endl;
return 0;
}
结果:
out contains 3 entries
术语 ""
不代表 std::string
实例,而是 const char*
文字,因此当您向其添加 ch
时,您正在执行指针运算并且可能会收到一条编译器警告:
warning: array subscript is above array bounds
到 push_back
一个 char
作为一个 std::string
到一个 std::vector<std::string>
只需做:
std::vector<std::string> vec;
char ch = 'a';
vec.push_back(std::string()+ch); // construct empty std::string, add ch, push_back
您的代码有问题。 这是类型特征,可帮助您检查名称是否为模板化类型:
/***Check if type is simple template***/
template <template<class...> class>
constexpr bool is_template_type()
{ return true; }
template <class>
constexpr bool is_template_type()
{ return false; }
有了这个,您可以检查 vector
是否是创建变量的有效类型。所以:
static_assert(!is_template_type<vector>(),
"vector is not valid type for creating a variable");
导致编译失败,因为无法创建class template
的变量。您必须指定 TYPE
,std::vector
应该存储。你的问题标题是:
vector of strings
所以您应该创建 std::vector<std::string>
变量。
您的代码的另一个问题是:
"" + ch
。
你认为它有什么作用? ""
类型为char const[1]
,ch
类型为char
。 char const[1]
可隐式转换为 char const *
,并且由于您可以将整数值添加到指针 - 它可以编译。但这不是你想要的!
这是你的 ""
记忆:
`[=12=]' ? ? ? ? ? ? ...
/\
将 ch
添加到 ""
后,结果如下:
//ch is 5 for example
`[=13=]' ? ? ? ? ? ? ...
/\
所以你用一些未指定的地址创建了 std::string
。实际上,访问数组 out-of-bounds 是 C++ 中的未定义行为。
您应该使用 std::string() + ch
或用户 W.F 的字符串文字语法。发表在他对你的问题的评论中。
另外不要忘记初始化ch
,因为使用未指定的值也是未定义的行为。