我不了解的C ++行为

问题描述 投票:0回答:1

我和我的朋友们都在使用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();
    }

}

此代码的输出:

A

当我注释掉第一行时,尝试阻止并取消注释第二行,这涉及到此:

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

    }

输出变为:

std:exception

我以为这可能是由于声明的变量(char,char *)的填充和对齐方式不同而引起的,但仍然不了解。您可以找到代码here来播放。预先感谢。

c++ vector type-conversion c++17 implicit-conversion
1个回答
6
投票
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

1
投票

@@ eerorika的答案解释了您的错误。

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

  1. [我接受Nicolai Jossutis的suggestion,试图用大括号统一初始化变量,此后没有相等值(例如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}; 
    
© www.soinside.com 2019 - 2024. All rights reserved.