Как можно использовать вектор таким образом? - PullRequest
2 голосов
/ 22 ноября 2011

Может кто-нибудь объяснить этот код, пожалуйста?почему функциональная панель принимает ссылку на первый элемент вектора?

jintArray arry;
std::vector<int> foo = GetIntegerArray(env, arry);
bar(&foo[0])

, где прототип bar равен

bar(int* array)

Ответы [ 4 ]

5 голосов
/ 22 ноября 2011

Это действительно, пока тип шаблона не bool.Тип вектора C ++ указывает, что векторные элементы являются последовательными в памяти, поэтому вы можете сделать именно это.

Причина, по которой он не работает с bool, заключается в специализации шаблона.Где bools сжаты до битового поля.

http://en.wikipedia.org/wiki/Vector_%28C%2B%2B%29#vector.3Cbool.3E_specialization

3 голосов
/ 22 ноября 2011

как получается, что функциональная панель принимает ссылку на первый элемент вектора?

Это, кажется, источник беспорядка. Выражение &foo[0] это не ссылка на первый элемент, а указатель. operator[] перегружен в классе vector для получения ссылки (или const-reference), а применение & получит адрес объекта.

2 голосов
/ 22 ноября 2011

Да. Просто убедитесь, что вектор не пуст, иначе &foo[0] будет ошибкой. В C ++ 11 появилась функция std::vector<T>::data(), которая не имеет этой проблемы.

Кроме того, возвращать вектор по значению обычно не очень хорошая идея. Возможно, вы захотите использовать выходной итератор или параметр ссылки на вектор в GetIntegerArray, поэтому вы бы назвали его так:

std::vector<int> foo;
GetIntegerArray(env, arry, back_inserter(foo));

или

std::vector<int> foo;
GetIntegerArray(env, arry, foo);
1 голос
/ 22 ноября 2011

Когда вы используете std::vector<int>, гарантируется, что все элементы создаются в непрерывной памяти.Таким образом, когда вы пишете &v[0], он возвращает указатель на первый элемент, и из этого вы можете перейти к следующему элементу, написав &v[0]+1 и т. Д.

Кстати, если вы хотитечтобы пройти через все элементы или часть элементов, лучший интерфейс для bar будет выглядеть так:

void bar(int *begin, int *end)
{
     for ( ; begin != end; ++begin)
     {
         //code
     }    
}

Так что вы можете позвонить так:

bar(&foo[0], &foo[0] + foo.size());//process all elements
bar(&foo[0], &foo[0] + foo.size()/2);//process first half elements
bar(&foo[0], &foo[0] + N); //process first N elements(assumingN <=foo.size())
bar(&foo[0]+foo.size()/2, &foo[0]+foo.size());//process second half elements
...