How to cheaply assign C-style array to std::vector?
The current std::vector
doesn't provide any capability or interface to take ownership of previously allocated storage. Presumably it would be too easy to pass a stack address in by accident, allowing more problems than it solved.
If you want to avoid copying into a vector, you'll either need to use vectors through your entire call chain, or do it the C way with float[]
the entire time. You can't mix them. You can guaranteed that &vec[0]
will be equivalent to the C-array though, fully contiguous, so using vector in the whole program may be feasible.
How to initialize std::vector from C-style array?
Don't forget that you can treat pointers as iterators:
w_.assign(w, w + len);
How to make a std::vectorT use an existing T* array without copying those values?
There is no interface into vector to make it take ownership of your pre-existing buffer. Even if you could shoe-horn it into the vector by using a custom allocator that provides this memory's address, the vector will consider it raw memory and overwrite it.
If it must be a vector, then you're out of luck without copying.
However, some sort of adaptive view on the existing buffer could give a container-like interface over your array without copying (such as the gsl::span as suggested in comments by Justin.)
gsl::span<int> s(myPtr, 4);
see https://github.com/Microsoft/GSL
and http://codexpert.ro/blog/2016/03/07/guidelines-support-library-review-spant/
How do I copy a C-style array into a void pointer in C++?
- As already commented above, using
void*
is not very useful. - If you need an array object, it's recommended in C++ to use either
std::array
for a fixed size array, orstd::vector
for dynamic size array. - This line:
array_private = pass_array_here
is simply assigning the pointer, not copying the array content. - If you use
std::array
orstd::vector
as suggested in point 2 above, you can utilize the copy constructor of these classes to actually copy the array's content easily:
void foo(std::vector<SomeType> const & pass_array_here) {
array_private = pass_array_here;
}
- If the caller of the function
foo
does not need to use the array after calling the function, you can save the copy of the data, and utilize C++ move semantics (available since C++ 11):
void foo(std::vector<SomeType> && pass_array_here) {
array_private = std::move(pass_array_here);
}
- If the caller does not have a
std::vector
but an old C style array, it is possible to initialize thestd::vector
member from it (which will copy the data). See: std::vector::assign.
For 4, 5 and 6 above, your private data member will have to be defined as:
std::vector<SomeType> array_private;
If you need to access the data buffer managed by an
std::vector
, you can usestd::vector::data
: std::vector::data. You can cast this data pointer into avoid*
if you need to pass it to a C style function, e.g. in opengl (no need to copy the data).More about move semantics and R value references here: Understanding rvalue references
C++ equivalent for C-style array
Question: is there an equivalent in C++ for C-style arrays in terms of performance?
Answer: Write C++ code! Know your language, know your standard library and use it. Standard algorithms are correct, readable and fast (They know the best how to implement it to be fast on the current compiler).
void testC()
{
// unchanged
}
void testCpp()
{
// unchanged initialization
for(j=0;j<1000;j++)
{
// how a C++ programmer accumulates:
count = std::accumulate(begin(v), end(v), 0);
}
// unchanged output
}
int main()
{
testC();
testCpp();
}
Output:
(C) For loop time [ms]: 434.373
1000000
(C++) For loop time [ms]: 419.79
1000000
Compiled with g++ -O3 -std=c++0x
Version 4.6.3 on Ubuntu.
For your code my output is similiar to yours. user1202136 gives a good answer about the differences...
What is the easiest way to initialize a std::vector with hardcoded elements?
One method would be to use the array to initialize the vector
static const int arr[] = {16,2,77,29};
vector<int> vec (arr, arr + sizeof(arr) / sizeof(arr[0]) );
Convert char** (c) of unknown length to vectorstring (c++)
You can simply use the constructor of std::vector
that takes two iterators:
const char* arr[] = {"Hello", "Friend", "Monkey", "Face"};
std::vector<std::string> v(std::begin(arr), std::end(arr));
Or if you really have a const char**
:
const char** p = arr;
std::vector<std::string> v(p, p + 4);
Which will also work with directly using arr
instead of p
due to array-to-pointer conversion.
Replace fixed size arrays with std::array?
AFAIK std::array
just provides a nicer STL-like interface to deal with rather than normal C-arrays. In terms of performances and capabilities the two choices boil down to be pretty much the same but std::array
can be used as a standard container.
Another feature: they might be treated like tuples since they provide tuple-like access functions.
Last but not the least as user2079303 noticed: if your code is going to be used by novice programmers, it can prevent the array decaying process when passing it as an argument.
If you're wondering if you should just replace all your C-style arrays with std::arrays, the answer is yes if you're going to exploit some of the newly available features and/or rewrite some of your code to take advantage of those capabilities. If you're just plain substituting C-arrays with std::arrays (without touching anything else) it might not be worth it.
C++ Move constructor for object with std::vector and std::array members
[...] and set the other's content to their default values?
No. When not stated otherwise a moved from object is in a valid, but unspecified state. Setting all elements to some default would be rather wasteful.
Further, a std::array
does contain the elements. Its not just a pointer to some dynamically allocated elements that could cheaply be moved. The elements are right within the array. Hence you can only move the individual elements, the array as a whole can only be copied. A std::array
is moveable when its elements are moveable, otherwise moving it will merely make a copy. For details I refer you to Is std::array movable?.
TL;DR
Vector(Vector&& other) = default;
is fine. You just expected it do something it does not do. Neither does moving set the moved from elements to some default, nor does moving the std::array<size_t,2>
actually move the elements, rather it copies them.
Related Topics
Braces Around String Literal in Char Array Declaration Valid? (E.G. Char S[] = {"Hello World"})
Why Can't We Declare Object of a Class Inside the Same Class
Specialization of 'Template<Class _Tp> Struct Std::Less' in Different Namespace
Opencv 2.4.3 iOS Framework Compiler Trouble Recognising Some C++ Headers
C++ Type of Enclosing Class in Static Member Function
Why Can't Redefine Type Names in Class in C++
Question About Pure Virtual Destructor
Application Has Failed to Start Because Msvcp100D.Dll Was Not Found, Reinstalling App May Work
Compiling an Application for Use in Highly Radioactive Environments
Std::Remove_If - Lambda, Not Removing Anything from the Collection
Adding Signals/Slots (Qobject) to Qgraphicsitem: Performance Hit
Inconsistent Strcmp() Return Value When Passing Strings as Pointers or as Literals
Glut Deprecation in MAC Osx 10.9, Ide: Qt Creator
How to Enforce C++ Compiler to Use Specific Crt Version
Skip Some Arguments in a C++ Function
Parsing Complete Messages from Serial Port
Convert Integer to Binary and Store It in an Integer Array of Specified Size:C++