为什么C ++没有为我们提供一个以数组作为参数的构造函数?或者,定义以下函数有什么问题吗?
template <class T>
std::set<T> ArrayToSet(T array[]) {
return std::set<T>(array, array + sizeof(array) / sizeof(array[0]));
}
我认为答案可能归结为动态内存分配的想法,但我希望听到一些反馈意见。
编辑:我没有使用C ++ 11。
答案 0 :(得分:6)
或者,定义以下函数有什么问题吗?
有:它不起作用。
您无法将可变长度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;
}
答案 1 :(得分:3)
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
也不起作用,它只会给你指针的大小,而不是数组。
答案 2 :(得分:3)
为什么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
的函数更有用。
看起来与Konrad在答案中的内容完全一样。