std :: begin可以使用数组参数吗?如果可以,怎么做? [英] Can std::begin work with array parameters and if so, how?

查看:253
本文介绍了std :: begin可以使用数组参数吗?如果可以,怎么做?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我无法使用 std :: begin() std :: end()(来自<带有c风格数组参数的code> iterator 库。

I have trouble using std::begin() and std::end() (from the iterator library) with c-style array parameters.

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出现以下错误(类似于结束) :

This results in the following error with Visual Studio 2010 (and similar for end):

error C2784: '_Ty *std::begin(_Ty (&)[_Size])' : could not deduce template argument for '_Ty (&)[_Size]' from 'const double []'
1>          c:\program files (x86)\microsoft visual studio 10.0\vc\include\xutility(995) : see declaration of 'std::begin'

将参数更改为非const会产生相同的结果。

Changing the parameter to non-const gives same result.

尝试将参数指定为

...
std::begin<const double, 3>(i_point), 
std::end<const double, 3>(i_point),
...

给予:

error C2664: '_Ty *std::begin<const double,3>(_Ty (&)[3])' : cannot convert parameter 1 from 'const double []' to 'const double (&)[3]'

是不是可以在数组参数上使用 std :: begin ,因为它们会衰减为指针?有没有解决这个问题的技巧,或者最好不要在数组参数上使用迭代器函数?

Is it just not possible to use std::begin on array parameters because they decay to pointers? Is there a trick to get around this or is it best just to not use the iterator functions on array parameters?

推荐答案

是的, std :: begin std :: end 可以使用C风格的参数数组。

Yes, std::begin and std::end can work with parameters that are C style arrays.

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

The trick is in passing a parameter that's a C style array. When you specify a 1D array as a normal parameter to a normal function, its type is silently adjusted from "array of T" to "pointer to T". When you call that function, what gets passed isn't the array (as an array), but a pointer to the first element of the array.

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

It is, however, possible to pass an array by reference to a function template:

template <class T, size_t N>
void function(T (&array)[N]) {
   // function body here
}

这个的情况下,你传递一个实际数组(尽管是通过引用)而不是指针,你可以使用 std :: begin std :: end 非常好。例如:

In this case, where you're passing an actual array (albeit, by reference) rather than a pointer, you can use std::begin and std::end perfectly well. For example:

template <class T, size_t N>
T sum(T (&array)[N]) { 
    return std::accumulate(std::begin(array), std::end(array), T());
}

现在传递一个数组是微不足道的,例如:

Now passing an array is trivial, such as:

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

auto total = sum(array);

std :: begin std :: end 本身的实现类似于 sum - 数组通过引用传递,因此它们看起来像这样:

std::begin and std::end themselves are implemented similarly to sum--the array is passed by reference, so they can look something like this:

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;
}

请注意,虽然最近这些已添加到标准中,但它们不会需要任何特别棘手的模板使用,所以上面的实现应该可以使用普通的旧C ++ 98编译器(如果内存服务,即使使用VC + 6之类的预标准编译器)。

Note that although these were added to the standard more recently, they don't require any particularly tricky use of templates, so the implementation above should work fine with a plain old C++98 compiler (and, if memory serves, even with pre-standard compilers such as VC++ 6).

这篇关于std :: begin可以使用数组参数吗?如果可以,怎么做?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆