STL Questions
1. Sorting a vector of custom objects
a)Using operator()
struct MyStruct {
int key;
std::string str;
MyStruct(int k, int s) : key(k), str(s) {}
};
struct less_than{
inline bool operator()(const MyStruct &s1, const MyStruct &b)
{
return s1.key<s2.key;
}
};
std::vector<MyStruct> vec;
vec.push_back(MyStruct(4, "a"));
vec.push_back(MyStruct(2, "b"));
vec.push_back(MyStruct(1, "c"));
vec.push_back(MyStruct(3, "d"));
std::sort(vec.begin(), vec.end(), less_than());
b)Using operator '<'
struct MyStruct {
int key;
std::string str;
MyStruct(int k, int s) : key(k), str(s) {}
bool operator<const MyStruct &s)
{
return key<s.key;
}
};
std::vector<MyStruct> vec;
vec.push_back(MyStruct(4, "a"));
vec.push_back(MyStruct(2, "b"));
vec.push_back(MyStruct(1, "c"));
vec.push_back(MyStruct(3, "d"));
std::sort(vec.begin(), vec.end());
c)Using lambda function
vector<MyStruct> vec;
sort(value.begin(), vec.end(),[](const MyStruct &lhs, const MyStruct &rhs)
{
return lhs.key<rhs.key;
});
2. Erase elements from a vector
Use the erase/remove idiom:
std::vector<int> vec{ 10, 20, 30, 20, 10, 40 };
vec.erase(std::remove(vec.begin(), vecc.end(), 20), vec.end());
3. push_back vs emplace_back
push_back create a temporary object and the copy/move, whereas emplace_back move/copy in place without temporary object.
emplace_back adds value at the endof vector/list. It is difficult from push_back() by the fact that it directly creates element at position whereas push_back() first makes
a temporary copy and copis from there. emplace_back() is faster in implementation than push_back() in most situations.
4. Why cant I make a vector reference
The component type of container like vectors must be assignable.
Reference are not assignable(you can only initialize them once when they are declared, and you cannot make themreference something else later.)
Othre non-assigned types are also not allowed as components of containers, eg. vector<const int> is not allowed.
5) Why is it wrong to use std::auto_ptr<> with standard container?
The c++ standard says that an STL element must be "copy-constructiable" and "assignable". In other words, an element must be able to assigned or copied and the two elements are logically independent.
std::auto_ptr doesnot fullfill this requirement.
For example:
class X {
};
std::vector<std::auto_ptr<X> vecx;
vecx.push_back(new X);
std::auto_ptr<X> px = vecx[0]; //vecx[0] is assigned NULL.
6. What is the most efficient way to erase duplicates and sort a vector?
std""sort(vec.begin(), vec.end());
vec.erase(std::unique(vec.begin(), vec.end()), vec.end());
Better to use "set", because it doesnot contain duplicate element.
set<int>s(vec.begin(),vec.end());
vec.assign(s.begin(), s.end());
7. What happens if you call erase() on a map element while iterating from begin to end?
Erase elements in a map doesnot invalidate any iterators. So invalidate it as below:
if(pm_it->second == delete_this_id)
{
pm_it = port_map.erase(pm_it);
}
8. std::map with user defined types as key
a) Use comparator object
struct classcompare
{
bool operator()(const class1 &lhs, const class1 &rhs) const
{
return lhs.id<rhs.id;
}
};
std::map<class1, int classcompare> c2;
b) Another way to achive the same as to specialize std::less
namespace std
{
template<>
struct less<class1>
{
bool operator()(const class1 &lhs, const class1 &rhs) const
{
return lhs.id<rhs.id;
}
};
}
The adcantage of this is that it will be picked by std::map "by default", and yet you do not expose operator < to client code.
9. Remove spaces from srd::string
str.erase(std::remove_if(str.begin(), str.end(), std::isspace), str.end());
10. Is there any real risk to deriveing from the c++ STL container?
The standard containers do not have virtual destructos, thus you cannot handle them polymorphically.
11. How to avoid memory leaks then using a vector of pointers to dynamically allocated objects in c++?
void foo()
{
vector <derived *> c;
for(unsigned int i =0; i<100;i++)
c.push_back(new derived());
}// leaks here
solutions
a) Usings for_each
std::for_each(c.begin(), c.end() delete_pointed<base>);
the problem is that, if there is exception between push_back and delete_pointed then there will be memory leaks.
b) Better to use smart pointer std::unique_ptr and std::shared_ptr
typedef std::vector<std::unique_ptr<base>> container;
for(unsigned i=0;i<100; i++)
container.push_back(make_unique<derived>());
12. Does std::vector use stack or heap memory and why?
vector<Type> vect; -> will allocate the vector, i.e. the header info on the stack, but the elements on the free store("heap");
vector<Type> *vect = new vector<Type>; -> will allocate everything on the free store.
vector<Type *>vect; -> will allocate the vector on the stack and a bunch of pointer on the free store.10
a)Using operator()
struct MyStruct {
int key;
std::string str;
MyStruct(int k, int s) : key(k), str(s) {}
};
struct less_than{
inline bool operator()(const MyStruct &s1, const MyStruct &b)
{
return s1.key<s2.key;
}
};
std::vector<MyStruct> vec;
vec.push_back(MyStruct(4, "a"));
vec.push_back(MyStruct(2, "b"));
vec.push_back(MyStruct(1, "c"));
vec.push_back(MyStruct(3, "d"));
std::sort(vec.begin(), vec.end(), less_than());
b)Using operator '<'
struct MyStruct {
int key;
std::string str;
MyStruct(int k, int s) : key(k), str(s) {}
bool operator<const MyStruct &s)
{
return key<s.key;
}
};
std::vector<MyStruct> vec;
vec.push_back(MyStruct(4, "a"));
vec.push_back(MyStruct(2, "b"));
vec.push_back(MyStruct(1, "c"));
vec.push_back(MyStruct(3, "d"));
std::sort(vec.begin(), vec.end());
c)Using lambda function
vector<MyStruct> vec;
sort(value.begin(), vec.end(),[](const MyStruct &lhs, const MyStruct &rhs)
{
return lhs.key<rhs.key;
});
2. Erase elements from a vector
Use the erase/remove idiom:
std::vector<int> vec{ 10, 20, 30, 20, 10, 40 };
vec.erase(std::remove(vec.begin(), vecc.end(), 20), vec.end());
3. push_back vs emplace_back
push_back create a temporary object and the copy/move, whereas emplace_back move/copy in place without temporary object.
emplace_back adds value at the endof vector/list. It is difficult from push_back() by the fact that it directly creates element at position whereas push_back() first makes
a temporary copy and copis from there. emplace_back() is faster in implementation than push_back() in most situations.
4. Why cant I make a vector reference
The component type of container like vectors must be assignable.
Reference are not assignable(you can only initialize them once when they are declared, and you cannot make themreference something else later.)
Othre non-assigned types are also not allowed as components of containers, eg. vector<const int> is not allowed.
5) Why is it wrong to use std::auto_ptr<> with standard container?
The c++ standard says that an STL element must be "copy-constructiable" and "assignable". In other words, an element must be able to assigned or copied and the two elements are logically independent.
std::auto_ptr doesnot fullfill this requirement.
For example:
class X {
};
std::vector<std::auto_ptr<X> vecx;
vecx.push_back(new X);
std::auto_ptr<X> px = vecx[0]; //vecx[0] is assigned NULL.
6. What is the most efficient way to erase duplicates and sort a vector?
std""sort(vec.begin(), vec.end());
vec.erase(std::unique(vec.begin(), vec.end()), vec.end());
Better to use "set", because it doesnot contain duplicate element.
set<int>s(vec.begin(),vec.end());
vec.assign(s.begin(), s.end());
7. What happens if you call erase() on a map element while iterating from begin to end?
Erase elements in a map doesnot invalidate any iterators. So invalidate it as below:
if(pm_it->second == delete_this_id)
{
pm_it = port_map.erase(pm_it);
}
8. std::map with user defined types as key
a) Use comparator object
struct classcompare
{
bool operator()(const class1 &lhs, const class1 &rhs) const
{
return lhs.id<rhs.id;
}
};
std::map<class1, int classcompare> c2;
b) Another way to achive the same as to specialize std::less
namespace std
{
template<>
struct less<class1>
{
bool operator()(const class1 &lhs, const class1 &rhs) const
{
return lhs.id<rhs.id;
}
};
}
The adcantage of this is that it will be picked by std::map "by default", and yet you do not expose operator < to client code.
9. Remove spaces from srd::string
str.erase(std::remove_if(str.begin(), str.end(), std::isspace), str.end());
10. Is there any real risk to deriveing from the c++ STL container?
The standard containers do not have virtual destructos, thus you cannot handle them polymorphically.
11. How to avoid memory leaks then using a vector of pointers to dynamically allocated objects in c++?
void foo()
{
vector <derived *> c;
for(unsigned int i =0; i<100;i++)
c.push_back(new derived());
}// leaks here
solutions
a) Usings for_each
std::for_each(c.begin(), c.end() delete_pointed<base>);
the problem is that, if there is exception between push_back and delete_pointed then there will be memory leaks.
b) Better to use smart pointer std::unique_ptr and std::shared_ptr
typedef std::vector<std::unique_ptr<base>> container;
for(unsigned i=0;i<100; i++)
container.push_back(make_unique<derived>());
12. Does std::vector use stack or heap memory and why?
vector<Type> vect; -> will allocate the vector, i.e. the header info on the stack, but the elements on the free store("heap");
vector<Type> *vect = new vector<Type>; -> will allocate everything on the free store.
vector<Type *>vect; -> will allocate the vector on the stack and a bunch of pointer on the free store.10
Comments
Post a Comment