need help to search element from vector of struct - c++

I have vector of struct partationPartItemTag_t type
typedef struct partationPartItemTag
{
std::string partition;
std::string partGroupId;
std::string mathTuid;
std::string partNumber;
tag_t itemTag;
}partationPartItemTag_t;
I want to find element from vector having value for partition == 'a' and partGroupId == 'b'
I have written following code and its working fine with C++11
But now i want to modify this code as I do not have c++11 support
partationPartItemTag_t mi={'a', 'b'};
vector<partationPartItemTag_t> searchlist;
searchlist.push_back(mi);
vector<partationPartItemTag_t>::iterator flag = std::search(partationPartItemTagVec.begin(),partationPartItemTagVec.end(),searchlist.begin(),searchlist.end(),[](partationPartItemTag_t &x, partationPartItemTag_t &y){
return ((x.partition.compare(y.partition) == 0) && (x.partGroupId.compare(y.partGroupId) == 0));
});
Please help me to modify this code i saw few posts for function pointer but I am not able to convert this using function pointer
Note: i want to chek value of 2 member in struct and I can not use lambda function or c++11
Thanks in advance.

A lambda is just a convenience functor that was introduced so that you can write these algorithms simpler.
But it's just a convenience. If you can't use them in this case, it's not the end of the world. After all, we couldn't for many many years. The solution is to just go back to using a functor:
struct SearchFor
{
/* ctor omitted for brevity */
std::string partition, partGroupId;
bool operator()(const partationPartItemTag_t& elem) const
{
return elem.partition == partition &&
elem.partGroupId == partGroupId;
}
};
And then use it in-line:
vector<partationPartItemTag_t>::iterator flag =
std::find_if(partationPartItemTagVec.begin(),
partationPartItemTagVec.end(),
SearchFor("a", "b"));

If you need to convert from C++11 to C++098 better option is to replace a lambda with a functor.
Define a functor compare as follows and call it in your algorithm in place of lambda.
struct compare
{
bool operator(partationPartItemTag_t x, partationPartItemTag_t y) const
{
return ((x.partition.compare(y.partition) == 0) &&
(x.partGroupId.compare(y.partGroupId) == 0) );
}
}
std::search(partationPartItemTagVec.begin(),
partationPartItemTagVec.end(),
searchlist.begin(),searchlist.end(),
compare(partationPartItemTag_t &x, partationPartItemTag_t &y) );

Related

What is the C++ way to do this instead of using function pointers?

I am working on a part of a program that applies different types of filters onto an already read data part of a bitmap image. The method in question gets the data stored in a 2-dim std::vector and furthermore a pointer to the function in which the filter is applied as arguments. By that we can generically apply different filters by using this method.
My question is, are function pointers the only way to achieve this, or does C++ offer a more beautiful and more readable solution to achieve it?
This is the method this question is about. Second argument is the function pointer that is used to access the function in the if/else statement inside the for loops.
void SteganoMessage::genFilter(std::vector<std::vector<uint32_t>> *d, uint32_t (*f)(uint32_t, size_t)){
int count = 0;
int pixel = getPixel();
for(auto itOuter = d->begin(); itOuter != d->end(); ++itOuter){
for(auto itInner = itOuter->begin(); itInner != itOuter->end(); ++itInner){
if(mode == true)
*itInner = f(*itInner, sizeof(*itInner));
else
*itInner = f(*itInner, this->getImage()->getBitmapHeader()->getBitCount()/8);
displayProgress(count, pixel);
}
}
displayProgress(0);
}
Call of genFilter function:
//...
{
genFilter(data, substB);
}
//...
While substB is a function of course.
Would be very thankful for a hint that leads me into the right direction where I could research or a code snippet that shows a possible more C++ like way to do it.
Type-preserving
The usual way to pass a function (or things that can be INVOKEd) in C++ is by using a template parameter:
// version #1
template <typename F>
void func(F f)
{
static_assert(std::is_invocable_v<F, std::uint32_t, std::size_t>);
// instead of f(*itInner, sizeof(*itInner))
std::invoke(f, *itInner, sizeof(*itInner));
}
You can also use SFINAE to prevent postponing the error to instantiation time. This also enables overloading:
// version #2
template <typename F>
std::enable_if_t<std::is_invocable_v<F, std::uint32_t, std::size_t>>
func(F f)
{
// no need to static_assert here
std::invoke(f, *itInner, sizeof(*itInner));
}
Since C++20, we can use concepts:
// version #3
template <std::Invocable<std::uint32_t, std::size_t> F>
void func(F f)
{
// same as above
}
Which can be simplified further, using an abbreviated function template, to:
// version #4
void func(std::Invocable<std::uint32_t, std::size_t> auto f)
{
// same as above
}
(This is still a function template rather than an ordinary function. It is equivalent to version #3.)
Type-erasing
You can also use std::function for type erasure:
// version #5
void func(std::function<void(std::uint32_t, std::size_t)> f)
{
// ...
f(*itInner, sizeof(*itInner));
}
Compared to the type-preserving alternatives (versions #1–4), this approach may reduce code bloat, but may incur runtime overhead for virtual function calling.
I agree with the already suggested comments and answer.
But if your question was about finding a way to avoid to pass a raw pointer to function as arguments and gain more control over the given filters, I think you can create a wrapping class with a functor that will handle the applied filters.
What is the motivation behind doing this ? Because a raw pointer to function does not give you the guarantee that the function is what you expect. You can pass any function which respect the prototype but is not a real filter and can do anything.
You can solve this problem this way (explanation below the code):
enum class FILTER_TYPE {MY_FILTER, MY_OTHER_FILTER};
class Filter
{
protected:
FILTER_TYPE f_type;
public:
Filter(FILTER_TYPE ft) : f_type(ft)
{}
uint32_t operator()(uint32_t a, size_t b) const
{
switch(f_type)
{
case FILTER_TYPE::MY_FILTER: return my_filter(a, b);
case FILTER_TYPE::MY_OTHER_FILTER: return my_other_filter(a, b);
}
}
private:
uint32_t my_filter(uint32_t a, size_t b) const
{
return a+static_cast<uint32_t>(b); // completely arbitrary
}
uint32_t my_other_filter(uint32_t a, size_t b) const
{
return a*static_cast<uint32_t>(b); // completely arbitrary
}
};
As you can see, you define all your different filters in the private section. Then you redefine the operator() in order to call the proper filter (selected by the FILTER_TYPE attribute).
Then, you can write your function this way:
void SteganoMessage::genFilter(std::vector <std::vector <uint32_t>> & data, const Filter & filter)
{
int count = 0;
int pixel = getPixel();
for(auto itOuter = data.begin(); itOuter != data.end(); ++itOuter)
{
for(auto itInner = itOuter->begin(); itInner != itOuter->end(); ++itInner)
{
if(mode == true)
*itInner = filter(*itInner, sizeof(*itInner));
else
*itInner = filter(*itInner, this->getImage()->getBitmapHeader()->getBitCount()/8);
displayProgress(count, pixel);
}
}
displayProgress(0);
}
This way, you have the guarantee that the argument is a well-defined filter, and you avoid the use of raw pointer to function (that make the code more readable).
I redefined the operator() in order to use the Filter instance as a function. It makes the code more intuitive in my opinion.
Last thing, I passed the data by reference instead of the address directly.
I hope it can be a good additional information.

Lambda with multiple parameters in find_if

I've got a vector with objects of a custom data type. One of the fields of this data type is an enum. I want to make sure that for all enum values at least one entry is added to the vector.
I want to use std::find_if() to check if the vector has an entry for a certain enum value. But I'm not sure how to write & use the lambda correctly. Here's what I got:
struct CustomType
{
EnumType type {EnumType::DEFAULT};
int x;
};
std::vector<CustomType> tmp;
// fetch values from database and add them to the vector
// for some EnumType values there might not be a record added to the vector
auto hasEnumType = [](const CustomType& customType, const EnumType& enumType) -> bool
{
return (customType.type == enumType);
};
// What do I replace '?' with to get the current position
if (std::find_if(tmp.begin(), tmp.end(), hasEnumType(?, EnumType::VALUE1)) != tmp.end())
{
//add CustomType with VALUE1 to vector
}
If you want to check against a fixed value, you can simply put it inside the lambda.
if ( std::find_if(tmp.begin(), tmp.end(), [](CustomType const & customType)
{ return customType.type == EnumType::VALUE; }) )
{ /* do something */}
If you want, in a sense, pass it to lambda as parameter, you can set it in an external variable and "capture" it by reference
auto enumType = EnumType::VALUE;
// capture variables by references --------V
if ( std::find_if(tmp.begin(), tmp.end(), [&](CustomType const & customType)
{ return customType.type == enumType; }) )
{ /* do something */ }
std::find_if takes a unary predicate as its third parameter. If you provide binary predicate it will fail type check.
One way to do this is to convert your binary predicate to unary predicate by capturing one of its parameters. To automate it for all enum values create a function that returns another function.
auto getTypeChecker = [](const EnumType enumType)
{
return [enumType](const CustomType& customType)
{
return (customType.type == enumType);
};
};
then declare a function that takes care of inserting enum values that are not present in the vector -
void insert_if_not_present(std::vector<CustomType>& vec, const EnumType type)
{
if(std::none_of(begin(vec), end(vec), getTypeChecker(type)))
{
//add CustomType with type to vec
}
}
Now call insert_if_not_present once for each enum value.
Note, here I have used std::none_of for convenience. You can use std::find_if in place of std::none_of in smae manner.

generically convert from boost::variant<T> to type

I have a typedef boost::variant<int, float, double, long, bool, std::string, boost::posix_time::ptime> variant which I use to store different types of values in a struct. Only one of the specific type is ever going to be stored in that struct, however I have a vector of these structs which I need to go through and get the actual type out of the variant.
Now when I need to do the conversion the types out of this variant I do this:
variant second = mystruct.variant;
if (second.which() == 5) //string
{
std::string val = boost::get<std::string>(second);
modvalue->AddNodeAttribute(key, val);
}
else if (second.which() == 0) //int
{
int val = boost::get<int>(second);
modvalue->AddNodeAttribute(key, val);
}
else if (second.which() == 2) //double
{
double val = boost::get<double>(second);
modvalue->AddNodeAttribute(key,val);
}
else if (second.which() == 1) //float
{
float val = boost::get<float>(second);
modvalue->AddNodeAttribute(key, val);
}
else if (second.which() == 3) // long
{
long val = boost::get<long>(second);
modvalue->AddNodeAttribute(key, val);
}
else if (second.which() == 4) // bool
{
bool val = boost::get<bool>(second);
modvalue->AddNodeAttribute(key, val);
}
else if (second.which() == 6) // posix::time
{
boost::posix_time::ptime ptm = boost::get<boost::posix_time::ptime>(second);
modvalue->AddNodeAttribute(key, ptm);
}
I wondered if there is a more generic way I can get around doing this by writing a generic function that takes the variant and a type T which is the return value. But when I do that I still have to write similar bunch of if statements to account for each type of T.
so something like FromVariant<int>(var);, but then I would still have to do it for each type in my variant.
So it seems that my generic solution doesn't reduce my code, but increase it, which obviously is not the point. I wondered if anyone has a more elegant solution to getting the various types out of my variant that is somewhat generic, where I can just call a function giving the type I want back?
Actually looking at your code some more, here is a different option - again based on using visitor..
struct add_node_visitor : boost::static_visitor<>
{
add_node_visitor(<type of modvalue> & node, <type of key> & key) : _node(node), _key(key) {}
template <typename _Item>
void operator()(_Item const& item)
{
node->AddNodeAttribute(_key, item);
}
<type of modvalue> & _node;
<type of key> & _key;
}
to use:
boost::apply_visitor (add_node_visitor(modmodvalue, key), mystruct.variant);
As long as your AddNodeAttribute has overloads for all types, the above should work...
When I was using boost::variant I would always access the contained data using visitor technique. In my opinion this is a very elegant way. It does not rely on switch-logic, which is really a sign of bad design. See the documentation.
Good luck!
... What does AddNodeAttribute do? Basically the same thing for each type, right? If you have a container of node attributes somewhere, then it basically needs to be a container of the variant type, right?
... So why not just rewrite AddNodeAttribute to be a single function accepting a variant?

Find array element by member value - what are "for" loop/std::map/Compare/for_each alternatives?

Example routine:
const Armature* SceneFile::findArmature(const Str& name){
for (int i = 0; i < (int)armatures.size(); i++)
if (name == armatures[i].name)
return &armatures[i];
return 0;
}
Routine's purpose is (obviously) to find a value within an array of elements, based on element's member variable, where comparing member variable with external "key" is search criteria.
One way to do it is to iterate through array in loop. Another is to use some kind of "map" class (std::map, some kind of vector sorted values + binarySearch, etc, etc). It is also possible to make a class for std::find or for std::for_each and use it to "wrap" the iteration loop.
What are other ways to do that?
I'm looking for alternative ways/techniques to extract the required element.
Ideally - I'm looking for a language construct, or a template "combo", or a programming pattern I don't know of that would collapse entire loop or entire function into one statement. Preferably using standard C++/STL features (no C++0x, until it becomes a new standard) AND without having to write additional helper classes (i.e. if helper classes exist, they should be generated from existing templates).
I.e. something like std::find where comparison is based on class member variable, and a variable is extracted using standard template function, or if variable (the one compared against "key"("name")) in example can be selected as parameter.
The purpose of the question is to discover/find language feature/programming technique I don't know yet. I suspect that there may be an applicable construct/tempalte/function/technique similar to for_each, and knowing this technique may be useful. Which is the main reason for asking.
Ideas?
If you have access to Boost or another tr1 implementation, you can use bind to do this:
const Armature * SceneFile::findArmature(const char * name) {
find_if(armatures.begin(), armatures.end(),
bind(_stricmp, name, bind(&string::c_str, bind(&Armature::name, _1))) == 0);
}
Caveat: I suspect many would admit that this is shorter, but claim it fails on the more elegant/simpler criteria.
Sure looks like a case for std::find_if -- as the predicate, you could use e.g. a suitable bind1st. I'm reluctant to say more as this smacks of homework a lot...;-).
Why 5 lines? Clean doesn't have a number attached to it. In fact, clean code might take more lines in the utility classes, which can then be reused over and over. Don't restrict yourself unnecessarily.
class by_name
{
public:
by_name(const std::string& pName) :
mName(pName)
{}
template <typename T>
bool operator()(const T& pX)
{
return pX.name == pName;
}
private:
std::string mName;
};
Then:
const Armature* SceneFile::findArmature(const char* name)
{
// whatever the iterator type name is
auto iter = std::find_if(armatures.begin(), armatures.end(), by_name(name));
return iter == armatures.end() ? 0 : &(*iter);
}
Within restriction:
class by_name { public: by_name(const std::string& pName) : mName(pName) {} template <typename T> bool operator()(const T& pX) { return pX.name == pName; } private: std::string mName; };
Then:
const Armature* SceneFile::findArmature(const char* name)
{
// whatever the iterator type name is
auto iter = std::find_if(armatures.begin(), armatures.end(), by_name(name));
return iter == armatures.end() ? 0 : &(*iter);
}
:)
C++0x has ranged-based for-loops, which I think would make the most elegant solution:
const Armature* SceneFile::findArmature(const std::string& pName) const
{
for (auto a : armatures)
{
if (a.name = pName) return &a;
}
return 0;
}
You would probably need to use STL map. It gives you possibility to get the element using keys. Your key would be the name of armature.
http://www.cplusplus.com/reference/stl/map/
EDIT: :D
one liner B-)
const Armature* SceneFile::findArmature(const Str& name){for (int i = 0; i < (int)armatures.size(); i++) if(name == armatures[i].name) return &armatures[i]; return 0;}
Holy shiz, you're using _stricmp? FAIL. Also, you didn't actually tell us the type of the vectors or any of the variables involved, so this is just guesswork.
const Armature* SceneFile::findArmature(const std::string& lols) {
for(auto it = armatures.begin(); it != armatures.end(); it++) {
if (boost::iequals(lols, (*it).name))
return &(*it);
return NULL;
}
Ultimately, if you need this, you should put the armatures or pointers to them in a std::map. A vector is the wrong container if you're searching into it, they're best for when the collection is what's important rather than any finding behaviour.
Edited to use a std::string reference.

Building a vector from components contained in another vector type

I have a code that looks something like this:
struct First
{
int f1;
int f2;
};
struct Second
{
First s1;
int s2;
};
std::vector < Second > secondVec;
Second sec;
sec.s1 = First();
secondVec.push_back(sec);
secondVec.push_back(sec);
std::vector < First > firstVec;
firstVec.reserve(secondVec.size());
for (std::vector < Second >::iterator secIter = secondVec.begin();
secIter != = secondVec.end();
++secIter)
{
firstVec.push_back(secIter->s1);
}
I'd like to replace this ugly for loop with a simple stl function that could perhaps perform the equivalent process. I was thinking that maybe std::transform could help me here, but I'm unsure as to how this could be written.
I'd also be interested if boost has anything to offer here.
If you have TR1 or Boost available, you could try this:
std::transform(secondVec.begin(),
secondVec.end(),
std::back_inserter(firstVec),
std::tr1::bind(&Second::s1, _1));
Define functor that will transform Second to First:
struct StoF { First operator()( const Second& s ) const { return s.s1; } };
Then use it in the following way:
transform( secondVec.begin(), secondVec.end(), back_inserter(firstVec), StoF() );
If your source vector contains a lot of elements you should consider resizing destination vector to make it work faster, as in #Goz answer:
firstVec.resize( secondVec.size() );
transform( secondVec.begin(), secondVec.end(), firstVec.begin(), StoF() );
Its not particularly difficult ... I tried this and it worked no problems.
struct First
{
int f1;
int f2;
};
struct Second
{
First s1;
int s2;
};
First Replace( Second& sec )
{
return sec.s1;
}
and then used the following code to copy it
std::vector < Second > secondVec;
Second sec;
sec.s1.f1 = 0;
sec.s1.f2 = 1;
secondVec.push_back(sec);
sec.s1.f1 = 2;
sec.s1.f2 = 3;
secondVec.push_back(sec);
std::vector < First > firstVec;
firstVec.resize( secondVec.size() );
std::transform( secondVec.begin(), secondVec.end(), firstVec.begin(), Replace );
You were right with your intuition. Although since you are using an empty vector, you should use a back inserter for your output iterator.
It should look like something of the like :
std::transform(secondVec.being(), secondVec.end(), back_inserter(firstVec), yourFunctor)
And yourFunctor looking like this :
void youFunctor(First param)
{
return param.s1;
}
Edit : Boost could help you with lambda function so you wouldn't have to create a separate functor for this task. You should also note that lambda function function are part of the TR1 and will be integrated to the C++ standard library.
Edit : Here is what Meredith was talking about with mem_fun (or member function adaptor).
struct Second
{
First s1;
int s2;
First getS1() const {return s1;};
};
And then the transform would look like this :
std::transform(secondVec.being(),
secondVec.end(),
std::back_inserter(firstVec),
std::mem_fun(&Second::getS1))