简体   繁体   English

我不明白的 C++ 行为

[英]C++ behavior that I don't understand

My friends and I were playing with the C++ language.我和我的朋友们正在玩 C++ 语言。 While doing so, we encountered something we couldn't understand.在这样做的过程中,我们遇到了一些我们无法理解的事情。

Here is the code:这是代码:

#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();
    }
}

Output for this code:此代码的输出:

A一种

When I comment out this first line try block and uncomment the second line, which comes to this:当我注释掉第一行 try 块并取消注释第二行时,结果如下:

try
{
    // std::vector<char> a = {pcha, pchb};
    std::vector<char> a = {pchb, pcha};
    print(a); 
}

Output becomes:输出变为:

std:exception标准:异常

I thought maybe the this occurs because of the different padding and alignments of the declared variables (char, char*), yet still didn't understand.我想这可能是因为声明的变量(char,char*)的不同填充和对齐方式导致的,但仍然不明白。 You can find the code here to play around.你可以在这里找到代码来玩。 Thanks in advance.提前致谢。

std::vector<char> a = {pcha, pchb};

Here, you use the constructor of vector that accepts two iterators to a range.在这里,您使用 vector 的构造函数,它接受一个范围内的两个迭代器。 Unless the end iterator is reachable from the begin one, the behaviour of the program is undefined.除非结束迭代器可从开始迭代器到达,否则程序的行为是未定义的。 Your two pointers are not iterators to the same range (ie elements of an array), so one is not reachable from the other.您的两个指针不是指向同一范围(即数组的元素)的迭代器,因此无法从另一个指针到达。 Therefore the behaviour of the program is undefined.因此程序的行为是未定义的。

These would be correct:这些是正确的:

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's answer explains your mistake. @eerorika 的回答解释了你的错误。

However, I would like to dissuade you, and other readers, from using the second part of the his(?) corrected code snippet - not because it's incorrect, but because it's problematic coding practice:但是,我想劝阻您和其他读者不要使用他(?)更正代码片段的第二部分 - 不是因为它不正确,而是因为它是有问题的编码实践:

  1. I accept Nicolai Jossutis' suggestion of trying to uniformly initialize variables with curly brackets and no equals since (eg. mytype myvar {my_initializer}; ).我接受 Nicolai Jossutis 的建议,即尝试使用大括号统一初始化变量并且没有等号(例如mytype myvar {my_initializer}; )。
  2. Freestanding pointers are dangerous beasts.独立式指针是危险的野兽。 Try to avoid them altogether, or minimize their existence to where you really need them.尽量避免使用它们,或者将它们的存在最小化到您真正需要它们的地方。 After all, you were "tempted" to use those pointers in an inappropriate way... so,毕竟,你被“诱惑”以不恰当的方式使用这些指针......所以,
     char arr[] {cha, chb}; std::vector<char> a = {std::begin(arr), std::end(arr)};
  3. Don't create a dummy container just to create the one you really want.不要仅仅为了创建您真正想要的容器而创建一个虚拟容器。 Just stick with the first line in @eerorika's suggestion (without the equals sign):只需坚持@eerorika 建议中的第一行(不带等号):
     std::vector<char> a {cha, chb};
  4. In fact, unless you really need it - you probably don't even want to create a variable-length container.事实上,除非你真的需要它——你可能甚至不想创建一个可变长度的容器。 So perhaps just所以也许只是
    std::array<char, 2> a {cha, chb};
    or with C++17's template argument deduction:或使用 C++17 的模板参数推导:
     std::array a {cha, chb};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM