繁体   English   中英

我不明白的 C++ 行为

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

我和我的朋友们正在玩 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 块并取消注释第二行时,结果如下:

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 的回答解释了你的错误。

但是,我想劝阻您和其他读者不要使用他(?)更正代码片段的第二部分 - 不是因为它不正确,而是因为它是有问题的编码实践:

  1. 我接受 Nicolai Jossutis 的建议,即尝试使用大括号统一初始化变量并且没有等号(例如mytype myvar {my_initializer}; )。
  2. 独立式指针是危险的野兽。 尽量避免使用它们,或者将它们的存在最小化到您真正需要它们的地方。 毕竟,你被“诱惑”以不恰当的方式使用这些指针......所以,
     char arr[] {cha, chb}; std::vector<char> a = {std::begin(arr), std::end(arr)};
  3. 不要仅仅为了创建您真正想要的容器而创建一个虚拟容器。 只需坚持@eerorika 建议中的第一行(不带等号):
     std::vector<char> a {cha, chb};
  4. 事实上,除非你真的需要它——你可能甚至不想创建一个可变长度的容器。 所以也许只是
    std::array<char, 2> a {cha, chb};
    或使用 C++17 的模板参数推导:
     std::array a {cha, chb};

暂无
暂无

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

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