我和我的朋友们在玩C++语言。在这样做的时候,我们遇到了一些我们无法理解的事情。
这是代码:
#include <vector>
#include <iostream>
void print(std::vector<char> const &input)
{
std::cout << input.size();
for (int i = 0; i < input.size(); i++)
{
std::cout << input.at(i) << " - ";
}
}
int main()
{
char cha = 'A';
char chb = 'B';
char * pcha = &cha;
char * pchb = &chb;
try
{
std::vector<char> a = {pcha, pchb};
//std::vector<char> a = {pchb, pcha};
print(a);
}
catch(std::exception e)
{
std::cout << e.what();
}
}
此代码的输出:
一个
当我注释掉第一行时,请尝试阻止并取消注释第二行,这是这样的:
try
{
// std::vector<char> a = {pcha, pchb};
std::vector<char> a = {pchb, pcha};
print(a);
}
输出变为:
标准:异常
我想这可能是因为声明的变量(char、char*(的填充和对齐方式不同而发生的,但仍然不明白。你可以在这里找到代码来玩。 提前谢谢。
std::vector<char> a = {pcha, pchb};
在这里,您使用 vector 的构造函数,该构造函数接受一个范围的两个迭代器。除非结束迭代器可以从开始迭代器到达,否则程序的行为是不确定的。您的两个指针不是指向同一范围的迭代器(即数组的元素(,因此一个指针无法从另一个指针访问。因此,程序的行为是未定义的。
这些是正确的:
std::vector<char> a = {cha, chb}; // uses initializer_list constructor
// or
char arr[] {cha, chb};
char * pcha = std::begin(arr);
char * pchb = std::end(arr);
std::vector<char> a = {pcha, pchb}; // uses the iterator constructor
@eerorika的回答解释了你的错误。
但是,我想劝阻您和其他读者不要使用他(?(更正的代码片段的第二部分 - 不是因为它不正确,而是因为它是有问题的编码实践:
- 我接受尼古拉·约苏蒂斯的建议,即尝试用大括号统一初始化变量,并且没有等号(例如
mytype myvar {my_initializer};
(。 - 独立式指针是危险的野兽。尽量完全避免它们,或者将它们的存在最小化到你真正需要它们的地方。毕竟,你被"诱惑"以不恰当的方式使用这些指针......所以
char arr[] {cha, chb}; std::vector<char> a = {std::begin(arr), std::end(arr)};
- 不要仅仅为了创建您真正想要的容器而创建一个虚拟容器。只需坚持@eerorika建议中的第一行(不带等号(:
std::vector<char> a {cha, chb};
- 事实上,除非你真的需要它 - 你可能甚至不想创建一个可变长度的容器。所以也许只是
或者用 C++17 的模板参数推导:std::array<char, 2> a {cha, chb};
std::array a {cha, chb};