从数组构造 std::set

Construct std::set from array

本文关键字:set std 数组      更新时间:2023-10-16

为什么C++不为我们提供将数组作为参数的构造函数?或者,定义以下函数有什么问题吗?

template <class T>
std::set<T> ArrayToSet(T array[]) {
  return std::set<T>(array, array + sizeof(array) / sizeof(array[0]));
}

我认为答案可能归结为动态内存分配的想法,但我想听到一些反馈。

编辑:我没有使用C++11。

或者,定义以下函数有什么问题吗?

有:它不起作用。

不能将可变长度的 C 样式数组传递给函数。参数列表中的T array[]语法是T* array的同义词:传递的是原始指针,而不是参数。

但是,您可以通过引用传递固定大小的数组(即 T (&array)[5]有效(。要使它适用于不同的数组长度,您需要使用非类型模板参数:

template <class T, std::size_t N>
std::set<T> ArrayToSet(T (&array)[N]) {
  return std::set<T>(array, array + N);
}

– 但我同意 Zac 的观点:该功能过于具体(或者,反过来:不够通用(。通过迭代器已经有一种通用的集合构造方法。所以正确的方法是使用 C++11 的 std::beginstd::end工具,如果你不能使用 C++11,那么正确的方法是自己编写:

template <typename T, std::size_t N>
T* begin(T (&array)[N]) {
    return array;
}
template <typename T, std::size_t N>
T* end(T (&array)[N]) {
    return array + N;
}

为什么C++不为我们提供将数组作为的构造函数 争论?

为什么会这样? std::set不是数组,并且它已经有一个构造函数,该构造函数需要迭代器来初始化它,因此不需要为数组添加另一个构造函数。 std::vector是一个数组,甚至它没有接受数组的构造函数。

或者,定义以下内容是否有任何错误 功能?

是和不是。 这是不必要的,因为你可以只写

MyType myArray[mySize];
std::set<MyType> mySet(myArray, myArray + sizeof(myArray) / sizeof(array[0]);
// or std::set<MyType> mySet(myArray, myArray + mySize);
// or std::set<MyType> mySet(std::begin(myArray), std::end(myArray)); c++11

真的不值得它自己的功能。

如果你真的想写一个函数来帮助你,我会通过将std::beginstd::end移植到 C++03 来解决这个问题。 这些至少比专门用于创建std::set的功能更有用。

它看起来与康拉德在他的回答中发布的一模一样。

std::set不需要

为 C 样式数组提供构造函数,因为可以使用迭代器从它们构造 - 此外,从数组构造并不容易,因为您可以尝试从 T * 构造,这不传达数组长度,或者它是否是一个数组。

为此,我们使用模板技巧来确定数组大小并使用迭代器构造函数:

template <typename T, size_t N>
std::set<T> ArrayToSet(T (& array)[N]) {
    return std::set<T>(&array[0], &array[0]+N);
}

请注意,如注释中所述,这不适用于T *类型。您可以为此重载,从而提供额外的参数arr_length或其他东西。在这种情况下,sizeof也不起作用,它只会给你指针的大小,而不是数组。