【问题标题】:How to access an element of an std::array given its pointer in C++如何在给定 C++ 指针的情况下访问 std::array 的元素
【发布时间】:2015-05-30 16:33:22
【问题描述】:

我正在尝试访问 std::array 的元素,因为它在 C++ 中给出了它的指针。这是一些说明我的问题的代码:

#include <iostream>
#include <array>

void func(std::array<int, 4> *);

int main()
{
    std::array<int, 4> arr = {1, 0, 5, 0};
    func(&arr);
}

void func(std::array<int, 4> *elements)
{
    for (int i = 0; i < 4; i = i + 1)
    {
        std::cout << *elements[i] << std::endl;
    }
}

我希望这会在新行上打印std::array 的每个元素。但是,它甚至没有通过编译:

main.cpp: In function ‘void func(std::array<int, 4ul>*)’:
main.cpp:16:22: error: no match for ‘operator*’ (operand type is ‘std::array<int, 4ul>’)
         std::cout << *elements[i] << std::endl;

这是怎么回事?
谢谢!

【问题讨论】:

  • 语法很笨拙,这是使用 & 引用而不是 * 指针传递数组的好理由。反正你也不喜欢 nullptr。

标签: c++ function pointers compiler-errors stdarray


【解决方案1】:

使用

std::cout << (*elements)[i] << std::endl;

相反。否则首先应用operator[],因为它具有更高的优先级,请参阅http://en.cppreference.com/w/cpp/language/operator_precedence

因此,您首先需要取消引用指针以访问第一个指针,即array,然后使用operator[] 访问数组。否则编译器会将您的代码解析为*(elements[i]),因此首先您会得到i-th 数组(除非i==0,否则它当然不存在),然后您尝试取消引用它,因此会出现编译错误。

提示:如果您担心副本,请改为通过 const 引用传递数组

void func(const std::array<int, 4>& elements)

那么你在函数中的语法将是“自然的”,即elements[i] 将简单地表示数组引用elements 的第i 个元素。您还可以将数组简单地传递为func(arr);

【讨论】:

    【解决方案2】:

    @vsoftco 的回答非常正确。

    我想补充一点,在C++ 中通过引用而不是指针传递大对象更习惯:

    #include <iostream>
    #include <array>
    
    // declare parameter as a reference
    void func(std::array<int, 4>&);
    
    int main()
    {
        std::array<int, 4> arr = {1, 0, 5, 0};
        func(arr); // no need to take address
    }
    
    void func(std::array<int, 4>& elements)
    {
        for (int i = 0; i < 4; i = i + 1)
        {
            // just use as normal
            std::cout << elements[i] << std::endl;
        }
    }
    

    如果函数不会修改数组,那么const reference会更合适:

    void func(const std::array<int, 4>& elements)
    {
        for (int i = 0; i < 4; i = i + 1)
        {
            // just use as normal
            std::cout << elements[i] << std::endl;
        }
    }
    

    【讨论】:

      【解决方案3】:

      替代答案

      虽然其他答案也是正确的,但我想建议另一种变体,因为在某些情况下重写代码以使用引用并不总是可能的:

      std::cout << elements->at(i) << std::endl;
      

      这是一个变体,它避免了指针解引用(*element),但使用了std::array::operator-&gt;。它也可能更易于阅读。

      【讨论】:

      • 小评论:std::array::at() 进行边界检查,这在调试代码时可以(并且推荐),但有时可能不希望它(例如,在边界检查会消耗 CPU 周期的高性能代码中) )。
      • @vsoftco,你是对的。 at() 函数进行边界检查。但是,边界检查可能是所有容器中 std::array 上最快的。因此,我不会将其仅用于调试代码。
      猜你喜欢
      • 1970-01-01
      • 2023-03-28
      • 1970-01-01
      • 2012-04-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多