Conversion of data type using auto in C++ - c++11

I have 2 vector container which contains 2 different kind of value with data type uint32_t. I want to print both of them together.
Like this is what I have
vector<uint32_t> data1;
vector<uint32_t> data2;
Now I know a method for single data like below
for(auto const& d1: data1)
cout<< d1 << endl;
But I want to print both data together like this,
cout<< d1 << "\t" << d2 << endl;
How can I do this using auto? (where d2 is auto converted value from data2)

You could use a normal for loop over the index:
for (auto i = 0u; i != n; ++i)
std::cout << data1[i] << "\t" << data2[i] << "\n";
Edit: if you want to convert the uint32_t to an int, for example, you could do:
auto d1 = static_cast<int>(data1[i]);
but it is up to you to ensure the conversion is safe. i.e the value fits in the target type.

Use the Boost Zip Iterator, which will let you have a range of pairs rather than two ranges of the vectors' data types. Something along the lines of:
#include <boost/iterator/zip_iterator.hpp>
#include <boost/range.hpp>
#include <stdint.h>
#include <vector>
#include <iostream>
template <typename... TContainer>
auto zip(TContainer&... containers) -> boost::iterator_range<boost::zip_iterator<decltype(boost::make_tuple(std::begin(containers)...))>> {
auto zip_begin = boost::make_zip_iterator(boost::make_tuple(std::begin(containers)...));
auto zip_end = boost::make_zip_iterator(boost::make_tuple(std::end(containers)...));
return boost::make_iterator_range(zip_begin, zip_end);
}
int main()
{
std::vector<uint32_t> data1( { 11, 22, 33 } );
std::vector<uint32_t> data2( { 44, 55, 66 } );
for (auto t : zip(data1, data2)) {
std::cout << boost::get<0>(t) << "\t" << boost::get<1>(t) << "\n";
}
}
The zip() function is due to this question and you can put it in a separate header file since it's not specific to your case.

If possible (and plausible for your use case): work with a container of pairs
If your application is not in a bind w.r.t. computer resources, and you know that you will be working with the values of your two containers as pairs (assuming same-length containers, as in your example), it might be useful to actually work with a container of pairs, which also ease the use of the neat range-based for loops ( >= C++11).
#include <iostream>
#include <vector>
#include <algorithm>
int main()
{
std::vector<uint32_t> data1 = {1, 2, 3};
std::vector<uint32_t> data2 = {4, 5, 6};
// construct container of (int, int) pairs
std::vector<std::pair<int, int>> data;
data.reserve(data1.size());
std::transform(data1.begin(), data1.end(), data2.begin(), std::back_inserter(data),
[](uint32_t first, uint32_t second) {
return std::make_pair(static_cast<int>(first), static_cast<int>(second));
}); /* as noted in accepted answer: you're responsible for
ensuring that the conversion here is safe */
// easily use range-based for loops to traverse of the
// pairs of your container
for(const auto& pair: data) {
std::cout << pair.first << " " << pair.second << "\n";
} /* 1 4
2 5
3 6 */
return 0;
}

Related

Error using Max_Element with String Vector

I'm implementing an algorithm to return a vector string array with only the largest elements in the vector string array of entrance:
vector<string> solution(vector<string> inputArray) {
vector<string> s;
auto m = *max_element(inputArray.begin(),inputArray.end());
for(int i=0;i<inputArray.size();i++){
if(inputArray[i].size() == m.size())
{
s.push_back(inputArray[i]);
}
}
return s;
It works for every test case except in the case the entry string vector is {"enyky", "benyky","yely","varennyky"}. 'm' should return a pointer to "varennyky", but it returns a pointer to "yely" instead.
I digged in to the documentation for max_element, but cant find what I'm doing wrong. Can anybody help me?
Your function is comparing the strings lexicographically, which is the default comparison in case of strings.
To illustrate, consider the following example:
#include <algorithm>
#include <string>
#include <vector>
// Print a vector of strings
void print_vec(std::vector<std::string> vec)
{
for (const auto& el : vec) {
std::cout << el << " ";
}
std::cout << std::endl;
}
// Compares strings by length
bool less_length(const std::string& s1, const std::string& s2)
{
return s1.length() < s2.length();
}
int main()
{
std::vector<std::string> test_0 = {"enyky", "benyky","yely","varennyky"};
// Default sort and max element
std::sort(test_0.begin(), test_0.end());
print_vec(test_0);
const auto largest_0 = *std::max_element(test_0.begin(), test_0.end());
std::cout << "Largest member (lexicographically): " << largest_0 << '\n' << std::endl;
// Sort and max element by string size
std::sort(test_0.begin(), test_0.end(), less_length);
print_vec(test_0);
const auto largest_1 = *std::max_element(test_0.begin(), test_0.end(), less_length);
std::cout << "Largest member (by string length): " << largest_1 << std::endl;
}
The first part of the program runs what you are doing in your function: it finds the maximum element based on lexicographic ordering. According to that ordering, the largest string is yely, you can see that by the output from sort.
The second part uses a custom comparison function, borrowed directly from this book. It uses string length to determine the order in the max_element call and the result is what you were looking for. Again, the sorted vector is also printed for clarity.

hash function for a 64-bit OS/compile, for an object that's really just a 4-byte int

I have a class named Foo that is privately nothing more than 4-byte int. If I return its value as an 8-byte size_t, am I going to be screwing up unordered_map<> or anything else? I could fill all bits with something like return foo + foo << 32;. Would that be better, or would it be worse as all hashes are now multiples of 0x100000001? Or how about return ~foo + foo << 32; which would use all 64 bits and also not have a common factor?
namespace std {
template<> struct hash<MyNamespace::Foo> {
typedef size_t result_type;
typedef MyNamespace::Foo argument_tupe;
size_t operator() (const MyNamespace::Foo& f ) const { return (size_t) f.u32InternalValue; }
};
}
An incremental uint32_t key converted to uint64_t works well
unordered_map will reserve space for the hash-table incrementally.
The less significant bits of the key is used to determine the bucket position, in an example for 4 entries/buckets, the less significant 2 bits are used.
Elements with a key giving the same bucket (multiple of the number of buckets) are chained in a linked list. This carry the concept of load-factor.
// 4 Buckets example
******** ******** ******** ******** ******** ******** ******** ******XX
bucket 00 would contains keys like {0, 256, 200000 ...}
bucket 01 would contains keys like {1, 513, 4008001 ...}
bucket 10 would contains keys like {2, 130, 10002 ...}
bucket 11 would contains keys like {3, 259, 1027, 20003, ...}
If you try to save an additional values in a bucket, and it load factor goes over the limit, the table is resized (e.g. you try to save a 5th element in a 4-bucket table with load_factor=1.0).
Consequently:
Having a uint32_t or a uint64_t key will have little impact until you reach 2^32-elements hash-table.
Would that be better, or would it be worse as all hashes are now multiples of 0x100000001?
This will have no impact until you reach 32-bits overflow (2^32) hash-table.
Good key conversion between incremental uint32_t and uint64_t:
key64 = static_cast<uint64>(key32);
Bad key conversion between incremental uint32_t and uint64_t:
key64 = static_cast<uint64>(key32)<<32;
The best is to keep the keys as even as possible, avoiding hashes with the same factor again and again. E.g. in the code below, keys with all factor 7 would have collision until resized to 16 buckets.
https://onlinegdb.com/r1N7TNySv
#include <iostream>
#include <unordered_map>
using namespace std;
// Print to std output the internal structure of an unordered_map.
template <typename K, typename T>
void printMapStruct(unordered_map<K, T>& map)
{
cout << "The map has " << map.bucket_count()<<
" buckets and max load factor: " << map.max_load_factor() << endl;
for (size_t i=0; i< map.bucket_count(); ++i)
{
cout << " Bucket " << i << ": ";
for (auto it=map.begin(i); it!=map.end(i); ++it)
{
cout << it->first << " ";
}
cout << endl;
}
cout << endl;
}
// Print the list of bucket sizes by this implementation
void printMapResizes()
{
cout << "Map bucket counts:"<< endl;
unordered_map<size_t, size_t> map;
size_t lastBucketSize=0;
for (size_t i=0; i<1024*1024; ++i)
{
if (lastBucketSize!=map.bucket_count())
{
cout << map.bucket_count() << " ";
lastBucketSize = map.bucket_count();
}
map.emplace(i,i);
}
cout << endl;
}
int main()
{
unordered_map<size_t,size_t> map;
printMapStruct(map);
map.emplace(0,0);
map.emplace(1,1);
printMapStruct(map);
map.emplace(72,72);
map.emplace(17,17);
printMapStruct(map);
map.emplace(7,7);
map.emplace(14,14);
printMapStruct(map);
printMapResizes();
return 0;
}
Note over the bucket count:
In the above example, the bucket count is as follow:
1 3 7 17 37 79 167 337 709 1493 3209 6427 12983 26267 53201 107897 218971 444487 902483 1832561
This seems to purposely follow a series of prime numbers (minimizing collisions). I am not aware of the function behind.
std::unordered_map<> bucket_count() after default rehash

Creating a C++ template function that allows multiple types of array containers

In modern C++ you can create arrays by three primary methods shown below.
// Traditional method
int array_one[] = {1, 2, 3, 4}
// Vector container
std::vector<int> array_two = {1, 2, 3, 4}
// array container
std::array<int, 4> array_three = {1, 2, 3, 4}
While each array method contains the same data, they are inherently different containers. I am writing a very simple Unit Test class with template functions to make it easier to pass multiple data types. I have an example shown below for the .hpp and .cpp calling file. The one method shown in the file takes a std::vector and compares it to another std::vector indice by indice to ensure that each value is within a certain tolerance of the other.
// main.cpp
#include <iostream>
#include <string>
#include <vector>
#include <array>
#include "unit_test.hpp"
int main(int argc, const char * argv[]) {
int array_one[] = {1, 2, 3, 4};
std::vector<int> array_two = {1, 2, 3, 4};
std::vector<float> array_four = {0.99, 1.99, 2.99, 3.99};
std::array<int, 4> array_three {1, 2, 3, 4};
std::string c ("Vector Test");
UnitTest q;
double unc = 0.1;
q.vectors_are_close(array_two, array_four, unc, c);
return 0;
}
and
#ifndef unit_test_hpp
#define unit_test_hpp
#endif /* unit_test_hpp */
#include <string>
#include <typeinfo>
#include <iostream>
#include <cmath>
class UnitTest
{
public:
template <class type1, class type2>
void vectors_are_close(const std::vector<type1> &i, const std::vector<type2> &j,
double k, std::string str);
private:
template <class type1, class type2>
void is_close(type1 &i, type2 &j, double k);
};
template <class type1, class type2>
void UnitTest::vectors_are_close(const std::vector<type1> &i, const std::vector<type2> &j,
double k, std::string str)
{
unsigned long remain;
remain = 50 - str.length();
if (i.size() != j.size()) {
std::cout << str + std::string(remain, '.') +
std::string("FAILED") << std::endl;
}
else {
try {
for (int a = 0; a < i.size(); a++){
is_close(i[a], j[a], k);
}
std::cout << str + std::string(remain, '.') +
std::string("PASSED") << std::endl;
} catch (const char* msg) {
std::cout << str + std::string(remain, '.') +
std::string("FAILED") << std::endl;
}
}
}
template <class type1, class type2>
void UnitTest::is_close(type1 &i, type2 &j, double k)
{
double percent_diff = abs((j - i) / ((i + j) / 2.0));
if (percent_diff > k) {
throw "Number not in Tolerance";
}
}
In this example the code compares two vectors; however, if I want to compare std::array containers I will have to crate a whole new function to do that, and if I want to compare two generic arrays, I will have to yet again create another function to do that. In addition, if I want to compare data in a std::array container to a std::vector container, again, I will have to create another function. I would like to create a single templated member function that I can pass any type of container to the function and have it compare it against any other type of container. In other words instead of;
void UnitTest::vectors_are_close(const std::vector<type1> &i, const std::vector<type2> & j);
I would like a simpler function such as;
void UnitTest::arrays_are_close(const type1, const type2);
where type1 and type2 do not just refer to the data in the container, but also the type of container as well. In this way I could pass a std::vector to type1 and std::array to type, or other combinations of the traditional way of creating arrays, array containers and vector containers. Is there any way to facilitate this behavior?
With a few changes to your implementation it is possible to do that:
template <class container1, class container2>
void UnitTest::vectors_are_close(const container1 &i, const container2 &j,
double k, std::string str)
{
unsigned long remain;
remain = 50 - str.length();
if (std::size(i) != std::size(j)) {
std::cout << str + std::string(remain, '.') +
std::string("FAILED") << std::endl;
}
else {
try {
for (int a = 0; a < std::size(i); a++){
is_close(i[a], j[a], k);
}
std::cout << str + std::string(remain, '.') +
std::string("PASSED") << std::endl;
} catch (const char* msg) {
std::cout << str + std::string(remain, '.') +
std::string("FAILED") << std::endl;
}
}
}
This function should work for std::vector, std::array and C-style arrays.

Boost Mem_fn and accessing member function of derived class

I made a simple example to test boost bind's interaction with derived classes.
I created two subclasses with different getarea functions. I expected
g1 = boost::bind(boost::mem_fn(&Shape::getarea), Rec)
to print the area of Rectangle(10,20) but instead it printed '1'. I get the same when I instead write Rectangle::getarea. It prints the same even when I input other functions eg. member of Rectangle
double sum(double h,double w){return h+w; }
and use
g1 = boost::bind(boost::mem_fn(&Rectangle::sum), Rec,2,3)
Question 1: Why does it return '1'?Is that a default response for error?
My second problem is to do the same of printing g2 but now Rec is replaced by **iter, i.e. an object of some derived class type from a list of objects. Since getarea is a virtual fcn, once I get the above working it should be fine to just write:
g2= boost::bind(boost::mem_fn(& Shape::getarea , &(**iter));
Question 2: However, I was wondering if there is a way to return the classtype of **iter eg. classof(**iter) and then put it in g2 i.e.
g2= boost::bind(boost::mem_fn(& classof(**iter)::getarea , &(**iter));
When I ran g2 by writing Shape::getarea, I got '1' again for all iter.
#include <memory>
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
#include <boost/bind.hpp>
using namespace std;
class Shape {
public:
Shape(double h, double w) :height(h), width(w) {};
virtual double getarea() = 0;
double height;
double width; };
class Rectangle: public Shape {
public:
Rectangle(double h, double w): Shape(h,w) {};
double getarea() override { return height*width; } };
class Triangle : public Shape {
public:
Triangle(double h, double w) :Shape(h,w) {};
double getarea() { return height*width*0.5; }};
int main() {
//create objects
Rectangle Rec(10, 20);
Triangle Tri(2, 3);
//create boost bind function
boost::function<double(double, double)> g1;
g1 = boost::bind(boost::mem_fn(&Shape::getarea), Rec);
//print area and g
cout << Rec.getarea()<<" should be equal to " << g1<< '\n';
//create list
vector<shared_ptr<Shape>> Plist;
Plist.push_back(make_shared<Rectangle>(Rec));
Plist.push_back(make_shared<Triangle>(Tri));
//print each element from the vector list
for (auto iter = Plist.begin(); iter != Plist.end(); iter ++ ) {
boost::function<double(double, double)> g2;
g2= boost::bind(boost::mem_fn(& .... , &(**iter));
//where in dots we need Classtype_of_**iter::getarea
cout << (**iter).getarea()<<"should be equal to " << g2<< '\n';
}
}
You... forget to invoke the functions...
for (auto iter = Plist.begin(); iter != Plist.end(); iter++) {
boost::function<double()> g2;
g2 = boost::bind(&Shape::getarea, iter->get());
cout << (*iter)->getarea() << " should be equal to " << g2() << '\n';
}
What you saw what the implicit conversion to bool (http://www.boost.org/doc/libs/1_60_0/doc/html/boost/function.html#idm45507164686720-bb)
Note also I fixed the signature of g1 and g2: Live On Coliru.
Some further improvements (remove the need for the g2 in the loop?):
auto getarea = boost::mem_fn(&Shape::getarea);
for (auto iter = Plist.begin(); iter != Plist.end(); iter++) {
cout << (*iter)->getarea() << " should be equal to " << getarea(**iter) << '\n';
}
Or, indeed in c++11:
for (auto& s : Plist)
cout << s->getarea() << " should be equal to " << getarea(*s) << '\n';
By this time, you'd wonder why you have this accessor when you can just use the member.

boost relocate function, what is the effect?

What does relocate() mean in boost multi-index container?
I have read the manual from boost documentations, but I want to see a simple example and see the difference of using and not using the relocate function. The examples on the web are not simple though....
It merely relocates (moves) item(s) in a sequenced index:
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/sequenced_index.hpp>
#include <iostream>
using namespace boost::multi_index;
typedef multi_index_container<
int,
indexed_by<sequenced<> >
> Ints;
int main()
{
Ints ints;
ints.insert(ints.end(), 1);
ints.insert(ints.end(), 2);
ints.insert(ints.end(), 3);
ints.insert(ints.end(), 4);
std::for_each (ints.begin(), ints.end(), [&](int i) { std::cout << i << std::endl; }); // 1, 2, 3, 4
auto i = find(ints.begin(), ints.end(), 2);
ints.relocate(ints.end(), i);
std::for_each (ints.begin(), ints.end(), [&](int i) { std::cout << i << std::endl; }); // 1, 3, 4, 2
}

Resources