从数组构造 std::set
Construct std::set from array
为什么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::begin
和std::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::begin
和std::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
也不起作用,它只会给你指针的大小,而不是数组。
- 在声明中合并两个常量"std::set"(不是在运行时)
- 有没有办法对std::unordered_set、std::unrdered_map、std::set、std::map
- 将 std::set 与基于键的比较器一起使用
- 修改"std::set"中用户定义类型的值
- 如何在构造函数参数中初始化"std::set"?
- 如何使用 lower_bound/upper_bound 从 std::set 获取索引号?
- 如何在 C++ 中转发声明 std::set?
- 重构使用动态强制转换的 std::set 的比较运算符
- 为什么 std::set.erase(first, last) 会影响从中获取 (first, last) 的容器?
- 将 std:set<int32_t> 复制到 std::set <uint32_t>的好方法
- 错误 C2676:std::set::const_iterator 没有运算符 + 函数?
- std::set 是否将对象连续存储在内存中?
- google test PrintTo for std::set<std::string>
- 不能对 std::set<std::string, std::less 使用用户提供的比较函数<>>
- "Flattening" std::set<std::string> 用于存储和比较?
- C++ std::map<std::string, std::set<std::string>> .如何循环设置值?
- 在std::set/std::map中存储具有多个不同类型字段的c++对象的有效方法
- 在C++中迭代 std::set<std::string> 时出现分段错误
- 从声明为 std::set<std::shared_ptr> edges_ 的edges_中删除边<Edge>;
- 将基于范围的 for 与 std::set<std::unique_ptr <T>一起使用>已删除函数