0

I'm new to C++11 and I'm confused about the usage of std::refence_wrapper class.

let's consider the example shown in https://en.cppreference.com/w/cpp/utility/functional/reference_wrapper ,which shuffles the elements contained in a standard std::vector, i.e:

std::vector<int> l(10); 
std::iota(l.begin(), l.end(), -4);
std::vector<std::reference_wrapper<int>> v(l.begin(), l.end());
std::shuffle(v.begin(), v.end(), std::mt19937{std::random_device{}()});

Now, if consider the original vector l, I have that l.data() returns a pointer to the internal array, which can I use in a C application.

Instead, it's not clear to me instead what is returned by v.data(). I tried various combinations of surely wrong casts, such as int* p = (int*)(v.data()->get()) without obtaining correct results (the swapped values).

My goal is to interface a C++ application (which gives me a vector of reference wrappers) with an old C library. Can you point me which is the most correct way to obtain a C-like array from the vector v, after the shuffle shown in the example? Do I need to copy all the elements one-by-one in another vector? Is there any C++11 class which can help me in the job? Thank you

4
  • 1
    In your code, l is a list, not a vector. It doesn't have a data() member function and if it did it wouldn't point to a C-style array. Commented Feb 14, 2019 at 19:08
  • I'm sorry, I made a mistake copy & pasting the snippet. I edited the question, so now l is a vector. Commented Feb 14, 2019 at 19:58
  • Why do you need std::reference_wrapper<int> in the first place? Do you plan to access the original array through these references? Commented Feb 14, 2019 at 20:13
  • 1
    @n.m. yes. The general idea is similar to the one reported in codereview.stackexchange.com/questions/114658/… in which multiple std::vector<std::reference_wrapper<int>> provide different 'views' of the internal data structure. Of course, when I access to the elements of the vector<reference_wrapper<int>> I want to modify data in the original data structure. But in this question, when I speak about a C-array obtained by .data() method, I just want to read data, not to modify it. Commented Feb 14, 2019 at 20:42

2 Answers 2

5

reference_wrapper is a C++ type; you're not supposed to be able to just hand it over to a C API. If you want to pass something to a C API, then it needs to be something that C and C++ share.

If that C API takes an array of pointers to integers, then pointers to integers is what your vector should store. Otherwise yes, you have to copy those integers into something that C can speak.

Sign up to request clarification or add additional context in comments.

2 Comments

I see your point. What do you think about the solution that I propose? (I just edited my question).
@MarcoRandazzo: Answers go in the answer box, not in your question.
0

After more thinking, I came up with this solution:

std::vector<int> l(10); 
std::iota(l.begin(), l.end(), -4);
std::vector<std::reference_wrapper<int>> v(l.begin(), l.end());
std::shuffle(v.begin(), v.end(), std::mt19937{std::random_device{}()});

std::vector<int> vec2 (v.begin(), v.end());
int* p = vec2.data();

I'm thus copying the elements from v to a new vector vec2. The C array p obtained from vec2 is now valid.

I wonder if there is a better way to do the job...

2 Comments

If C expects an int*, then you have to have either a int[] or a vector<int> that holds the final data. There's no "better" way.
If you can change the C to expect an array of int pointers, then you can have a vector<int*> the entire time. You need to manually handle the derefencing then instead of letting std::reference_wrapper do it but it doesn't take an extra copy for the C side.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.