C++ Convert Vector<Int> to Vector<Double>

C++ convert vector int to vector double

Use std::vector's range constructor:

std::vector<int> intVec;
std::vector<double> doubleVec(intVec.begin(), intVec.end());

C++ 2D vector - Convert int to double

Here's a pretty simple solution which uses emplace_back and the vector range constructor:

std::vector<std::vector<int>> intvec;
//intvec filled somehow

std::vector<std::vector<double>> doublevec;
doublevec.reserve(intvec.size());
for (auto&& v : intvec) doublevec.emplace_back(std::begin(v), std::end(v));

How to convert vector to array

There's a fairly simple trick to do so, since the spec now guarantees vectors store their elements contiguously:

std::vector<double> v;
double* a = &v[0];

Convert vector double to vector string ( elegant way )

There are many ways, but a standard solution is to use std::transform with a lambda using std::to_string for the conversion :

std::transform(std::begin(doubleVec),
std::end(doubleVec),
std::back_inserter(doubleStr),
[](double d) { return std::to_string(d); }
);

And you can wrap that in a function template to make it work with any Standard compliant container :

template<class IteratorIn, class IteratorOut>
void to_string(IteratorIn first, IteratorIn last, IteratorOut out)
{
std::transform(first, last, out,
[](typename std::iterator_traits<IteratorIn>::value_type d) { return std::to_string(d); } );
}

Or in C++14, with a generic lambda :

template<class IteratorIn, class IteratorOut>
void to_string(IteratorIn first, IteratorIn last, IteratorOut out)
{
std::transform(first, last, out, [](auto d) { return std::to_string(d); } );
}

And call it with any container (i.e. it works with std::list<int>, for instance) :

to_string(std::begin(doubleVec), std::end(doubleVec), std::back_inserter(doubleStr));

Notes :

  • If you don't have a C++11 compiler, write your own to_string function template :

Example:

template<class T>
std::string my_to_string(T v)
{
std::stringstream ss;
ss << v;
return ss.str();
}

And use it in a similar way :

std::transform(doubleVec.begin(),
doubleVec.end(),
std::back_inserter(doubleStr),
my_to_string<double> );
  • You should reserve() the memory in the output vector to avoid reallocations during std::transform() :

e.g. do this :

std::vector<std::string> stringVec;
stringVec.reserve(v.size()); // reserve space for v.size() elements

Live demo

implicit conversion of vector from one type to another c++

No, there is no conversion (implicit or otherwise) between different vector types.

You could initialise it from an iterator range:

std::vector<double> doubleVec(intVec.begin(), intVec.end());

perhaps wrapping this in a function:

template <typename To, typename From>
To container_cast(From && from) {
using std::begin; using std::end; // Koenig lookup enabled
return To(begin(from), end(from));
}

auto doubleVec = container_cast<std::vector<double>>(intVec);

Safe to assign vector int to vector double ?

I think this is safe, since assign is a template. See http://www.cplusplus.com/reference/stl/vector/assign/. The implementation assigns doubles from ints, which basically is not different to your other solution. Checking the header in /usr/include/c++/4.6/bits/stl_vector.h it seems the constructer and assign both call the same internal function, _M_assign_dispatch.

C++ convert vector containing objects to vector containing doubles

You could use std::transform. For example if you have a class

class Foo {
double val;
public:
Foo() = default;
Foo(double const val_) : val(val_) {}
double getVal() const { return val; }
};

In your program do:

std::vector<Foo> v {{1.2}, {2.3}, {5.6}};  
std::vector<double> dv(v.size());
std::transform(v.begin(), v.end(), dv.begin(), [](auto const &f) { return f.getVal(); });

Live Demo

If your compiler doesn't support C++14 generic lambdas change to:

std::transform(v.begin(), v.end(), dv.begin(), [](Foo const &f) { return f.getVal(); });

Convert vector int8 to vector uint8

You can use the constructor that accepts a range of iterators:

std::vector<uint8>(std::begin(signed_vec), std::end(signed_vec));

That said, in case you don't actually need a std::vector<uint8> object, but rather simply want to read a range of unsigned integers, you can reinterpret them instead:

uint8* ptr_beg = reinterpret_cast<uint8>(signed_vec.data());
uint8* ptr_end = ptr_beg + signed_vec.size();

Conversion between unsigned and signed versions of the same integer size is one of the rare cases where reinterpretation is well defined.

Convert vector std::string to vector double

For completeness (since Chris removed the edit from his answer):

std::vector<double> doubleVector(stringVector.size());
std::transform(stringVector.begin(), stringVector.end(), doubleVector.begin(), [](const std::string& val)
{
return std::stod(val);
});

Comparison to using std::back_inserter without reserve

Without reserve, you run the risk of having to resize the array each time the back_inserter calls push_back. It has to check the current size against the current capacity, and if the capacity needs to be increased, it will copy the vector to a new location (with increased capacity). After all of that, it will increase the size and insert the new element. This is a lot of overhead when you know what the size should be to start with (it will match the size of the stringVector).

Comparision to using std::back_inserter with reserve

Reserving the proper amount of memory will prevent the reallocation problem, but push_back still updates the size and does the check to see if the capacity has been reached each iteration. You've reduced the overhead a lot (no longer running the risk of having to "move" the array because of sizing issues), but you still have a lot of unneeded conditional checks.

Setting the size initially has a small overhead of setting all the elements to a default value (0.0 in the case of doubles). With each iteration, you are then simply setting the value of the current element. So for a vector of N elements, you have 2N + 2 assignments (setting the capacity, size, the initial value of the elements, and the real value of the elements) with no unneeded conditional checks. The reserve method has 2N + 1 assignments (set the capacity once, update the size N times, and set the value of N doubles) in addition to N conditional checks.

If you really wanted to optimize it even further, you could create your own iterator wrapper that does the conversion, which would then allow you to write the correct value for the doubles when you initialize the vector:

// pseudo-code
std::vector<double> doubleVector(my_string_conversion_iterator(stringVector.begin()), my_string_conversion_iterator(stringVector.end());


Related Topics



Leave a reply



Submit