Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ std::是否可以开始使用数组参数?如果可以,如何开始?_C++_Arrays_Stl_Iterator_Std - Fatal编程技术网

C++ std::是否可以开始使用数组参数?如果可以,如何开始?

C++ std::是否可以开始使用数组参数?如果可以,如何开始?,c++,arrays,stl,iterator,std,C++,Arrays,Stl,Iterator,Std,我无法使用带有c样式数组参数的std::begin()和std::end()(来自迭代器库) void SetOrigin(const double i_point[3]) { Vector v; std::copy( std::begin(i_point), std::end(i_point), v.begin()); this->setOrigin(v); } 这会导致Visual Studio 2010出现以下错误(end也有类似错误): 将

我无法使用带有c样式数组参数的
std::begin()
std::end()
(来自
迭代器
库)

void SetOrigin(const double i_point[3]) {
  Vector v;
  std::copy(
    std::begin(i_point), 
    std::end(i_point), 
    v.begin());
  this->setOrigin(v);
}
这会导致Visual Studio 2010出现以下错误(end也有类似错误):

将参数更改为non-const会得到相同的结果

正在尝试将参数指定为

...
std::begin<const double, 3>(i_point), 
std::end<const double, 3>(i_point),
...
。。。
标准::开始(i_点),
标准::结束(i_点),
...
给出:

error C2664: '_Ty *std::begin<const double,3>(_Ty (&)[3])' : cannot convert parameter 1 from 'const double []' to 'const double (&)[3]'
错误C2664:“_Ty*std::begin(_Ty(&)[3]):无法将参数1从'const double[]转换为'const double(&)[3]”
难道不能对数组参数使用
std::begin
,因为它们会衰减为指针吗?有什么技巧可以绕过这个问题,还是最好不要对数组参数使用迭代器函数

void SetOrigin(const double i_point[3])

void SetOrigin(const double i_point[])

所以,
std::begin
std::end
不能接受它。在C++中,不能传递数组,但不能作为指针或引用。如果它是一个指针,那么它不携带传递的数组的任何信息


您的备选方案是
std::vector
std::array

您看过std::array吗


它可以更好地与其他STL组件配合使用

首先,请注意参数声明
常量双i_点[3]
绝对等同于
常量双*i_点
。也就是说,该函数接受指向双常量的任何指针,与指向的元素数无关。因此,它不知道大小,
std::begin()
std::end()
无法推断大小(好吧,
std::begin()
实际上并不需要推断大小)

如果您确实想使用
std::begin()
std::end()
,则需要传递一个包含三个元素的数组或对此类beast的引用。由于无法按值传递数组,因此最好按引用传递:

void SetOrigin(double const (&i_point)[3]) {
    // ...
}

此函数只接受正好有三个元素的数组作为参数:不能将指针传递给三个
double
s或更大数组的一部分。作为回报,您现在可以使用
std::begin()
std::end()
而不直接回答您的问题(和已经充分回答了这个问题),您似乎想在此函数中初始化一些
std::vector
。也就是说,为什么不:

std::vector v;
std::copy(std::begin(x), std::end(x), std::back_inserter(v));
// or std::copy(x, x + 3, std::back_inserter(v));
而不是对尝试执行此操作的函数进行函数调用

或者,您可以这样编写函数:

template<typename RandomIterator>
void SetOrigin(RandomIterator start, RandomIterator end)
{
    std::vector<int> v;
    std::copy(start, end, std::back_inserter(v));
    SetOrigin(v);
}
template <class T, size_t N>
T *begin(T (&array)[N]) { 
    return array; 
}

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

是的,
std::begin
std::end
可以使用C样式数组的参数

诀窍在于传递一个C样式数组的参数。当您将1D数组指定为普通函数的普通参数时,其类型将从“T数组”静默调整为“指向T的指针”。调用该函数时,传递的不是数组(作为数组),而是指向数组第一个元素的指针

但是,可以通过引用函数模板来传递数组:

template <class T, size_t N>
void function(T (&array)[N]) {
   // function body here
}
现在传递数组很简单,例如:

int array[] = {1, 2, 3, 4};

auto total = sum(array);
std::begin
std::end
本身的实现方式类似于
sum
——数组是通过引用传递的,因此它们可以如下所示:

template<typename RandomIterator>
void SetOrigin(RandomIterator start, RandomIterator end)
{
    std::vector<int> v;
    std::copy(start, end, std::back_inserter(v));
    SetOrigin(v);
}
template <class T, size_t N>
T *begin(T (&array)[N]) { 
    return array; 
}

template <class T, size_t N>
T *end(T (&array)[N]) {
    return array + N;
}
模板
T*begin(T(&数组)[N]){
返回数组;
}
模板
T*结束(T(&数组)[N]){
返回数组+N;
}

请注意,尽管这些是最近才添加到标准中的,但它们不需要特别复杂的模板使用,因此上述实现应该可以在普通的旧C++98编译器上正常工作(如果内存可用,甚至可以使用诸如VC++6之类的预标准编译器)。

i_point[3]
的行为类似于平面指针,而不是实数数组,当用作函数参数时。对数组类型的局部变量尝试同样的方法,它应该可以工作。
const double i_point[3]
这个函数参数将衰减为
const double*i_point
,您可以使用
const double(&i_point)[3]
(对于需要数组的函数,只需传递一对指针)精度就是一切:
std::array
(注意
a
vs.
a
);-)@DietmarKühl这不是一个精度问题吗?确实是这样,但我只是想为那些想用c样式数组作为参数调用我的函数的人提供一个接口。我有另一个版本可以接受
std::array
@GlennTeitelbaum:touché!英语不是我的母语,我几乎不能表达自己。@chris:完全忘记了。我刚才提到过。谢谢。在这种情况下,我不是在尝试你所怀疑的,但如果我是的话,我明白你的意思。
int array[] = {1, 2, 3, 4};

auto total = sum(array);
template <class T, size_t N>
T *begin(T (&array)[N]) { 
    return array; 
}

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