【问题标题】:Difference between const std::array<T,N> and std::array<const T, N>const std::array<T,N> 和 std::array<const T, N> 之间的区别
【发布时间】:2022-01-21 14:36:15
【问题描述】:

std::array&lt;const T, N&gt;const std::array&lt;T, N&gt; 之间有什么实际区别吗?

看起来包含 const 元素的非常量数组仍然无法交换;赋值运算符也不起作用。

什么时候我应该更喜欢一个而不是另一个?

#include <array>

std::array<const int, 5> array_of_const = {1,2,3,4,5};
std::array<const int, 5> array_of_const2 = {1,2,3,4,5};

const std::array<int, 5> const_array = {1,2,3,4,5};
const std::array<int, 5> const_array2 = {1,2,3,4,5};

int main()
{
    // Assignment doesn't work for either
    array_of_const = array_of_const2;
    const_array = const_array2;

    // Swapping doesn't work for either
    array_of_const.swap(array_of_const2);
    const_array.swap(const_array2);

    // Indexing...
    array_of_const[0] = 0;
    const_array[0] = 0;

    return 0;
};

【问题讨论】:

  • @DrewDormann 是的,我同意。我想不出有什么好的理由,
  • @KarlKnechtel [language-lawyer] 实际上不是由 OP 添加的
  • 我不明白为什么这有很多赞成票。 (最初的可能是平衡投票(我认为这很糟糕)我猜)
  • @ildjarn 什么“巨大的、明显的实际差异”?我没有看到任何
  • @wooc 在 ildjarn 的辩护中,这不是 最清晰 的例子。我最初认为它也指出了不同之处。

标签: c++


【解决方案1】:

std::array&lt;const T, N&gt; 的副本仍然是“逻辑上的 const”,而默认情况下 const std::array&lt;T, N&gt; 的副本是可变的。如果允许或阻止这对您来说很重要,那么一个比另一个更可取。

它们匹配的模板存在差异,例如Ilya's answer中的案例。

【讨论】:

    【解决方案2】:

    可能至少存在一种差异 - 当您需要将变量传递给其他函数时,例如:

    #include <array>
    
    std::array<const int, 5> cc_arr5 = {1,2,3,4,5};
    const std::array<int, 5> cc_arr5_2 = {1,2,3,4,5};
    
    template<class T, std::size_t N>
    void func(std::array<T, N>& a) {
        // do not change a, for example just calculate sum
    }
    
    int main()
    {
        func(cc_arr5);
        func(cc_arr5_2); // this line does not compile
    
        return 0;
    };
    

    【讨论】:

    • 嗯,差异就是差异,即使它是人为的。虽然我们都看到过使用非常量引用然后实际上并没有改变参数的函数,所以我想这并不是那么做作。
    • 正是我即将发布的示例......有一些独角兽积分比我快几分钟。
    • 考虑扩展这个例子,证明 a 不需要在函数体中被改变以使其工作? godbolt.org/z/qqPc9qW77
    • 当然,通过值传递std::span 比通过引用传递std::array 或本机数组更可取...
    • 现在唯一缺少的是const std:array&lt;const int, 5&gt; 的示例。
    【解决方案3】:

    它们确实是不同的类型,所以你不能在一个地方使用一个,而不管另一个是预期的,例如在函数调用或赋值中。

    话虽如此,由于数组是一个没有辅助数据成员的固定大小的容器,因此容器 const 可以防止对其元素进行任何更改,并且元素 const 不允许对容器进行任何更改,因为它显然没有其他数据成员。

    换句话说,这两种类型将具有完全相同的有效和无效操作。

    我能想到的主要区别是 const_cast 含义:一个数组可以(隐式)转换为相同元素类型的 const 数组,但不能转换为 const 修改类型的数组:

    std::array<int, 3> a {1, 2, 3};
    
    std::array<const int, 3> b = a; // Error: no known conversion from 'array<int, [...]>' to 'const array<const int, [...]>
    const std::array<int, 3> c = a; // Ok
    

    【讨论】:

    • 也许 两个 const_cast 含义:这两种类型中的一种也可以丢弃const
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-10-05
    • 2021-06-02
    • 1970-01-01
    • 2020-05-21
    • 2019-01-28
    • 2017-10-01
    • 2016-05-03
    相关资源
    最近更新 更多