const std::array<T,N> 和 std::array<const T, N> 之间的区别

woo*_*hek 46 c++

std::array<const T, N>和之间有什么实际区别吗const std::array<T, N>

看来保存 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;
};
Run Code Online (Sandbox Code Playgroud)

Cal*_*eth 41

的副本std::array<const T, N>仍然是“逻辑常量”,而默认情况下, 的副本const std::array<T, N>是可变的。如果允许或阻止这对您很重要,那么其中一个比另一个更可取。

它们匹配的模板存在差异,例如Ilya 的回答中的情况。


Iły*_*sov 22

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

#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;
};
Run Code Online (Sandbox Code Playgroud)

  • 好吧,差异就是差异,即使它是人为的。尽管我们都在野外见过采用非常量引用的函数,但实际上并没有改变参数,所以我想这并不是那么做作。 (2认同)
  • 当然,按值传递 [`std::span`](//en.cppreference.com/w/cpp/container/span) 比按引用传递 `std::array` 或本机数组要好得多。 .. (2认同)

Ser*_*sta 9

它们确实是不同的类型,因此您不能在某个地方使用一种类型,而不管另一种类型是否需要,例如在函数调用或赋值中。

话虽这么说,由于数组是没有辅助数据成员的固定大小容器,因此容器 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
Run Code Online (Sandbox Code Playgroud)