Lambda Expression in c++ std::copy_if - c++

Can somebody explain or help me why this isnt working?
std::vector<std::shared_ptr<Publication> > Bibliography::givePubWithIFHigherThan(float value) const
{
Publication *p;
std::vector<std::shared_ptr<Publication>> highIFPubs(publications);
auto checkIF = std::mem_fun(p->IFHigherThan(value));
auto last = std::copy_if(publications.begin(), publications.end, highIFPubs.begin(),
[=] (std::shared_ptr<Publication> p)
{
return checkIF(*p, value);
});
return highIFPubs;
}
class Publication
{
public:
Publication(std::string aTitle, int aYear, std::string anID);
virtual bool IFHigherThan(float value) const {return false;};
private:
};
class Paper : public Publication
{
public:
Paper(std::string aTitle, int aYear, std::string aJournal, float aImpactFactor);
bool IFHigherThan(float value) const {return value < impactFactor;};
private:
};
At the moment i get this error,
no matching function for call to 'mem_fun(bool)'
auto checkIF = std::mem_fun(p->IFHigherThan(value));
^

std::mem_fun is a depracated helper function that will probably be soon removed from the standard library. std::mem_fn would be a better choice.
Moreover, if you want to use std::mem_fn, std::mem_fun or std::bind with a function, then you pass in a pointer to function, not a call expression, so instead of:
auto checkIF = std::mem_fun(p->IFHigherThan(value));
use:
auto checkIF = std::mem_fn(&Publication::IFHigherThan);
Alternatively, don't use any wrapper, just directly call the selected member function:
auto last = std::copy_if(publications.begin(), publications.end(), highIFPubs.begin(),
[=] (std::shared_ptr<Publication> p)
{
return p->IFHigherThan(value);
});
There is one more logical error you have in your code:
std::vector<std::shared_ptr<Publication>> highIFPubs(publications.size());
should be:
std::vector<std::shared_ptr<Publication>> highIFPubs;
and then instead of:
auto last = std::copy_if(publications.begin(), publications.end()
, highIFPubs.begin(),
// ~~~~~~~~~~~~~~~~~^
you should be using std::back_inserter:
auto last = std::copy_if(publications.begin(), publications.end()
, std::back_inserter(highIFPubs),
// ~~~~~~~~~~~~~~~~~^
as you don't actually know how many elements will the resultant vector have.

Related

How to have the compiler deduce the return type of a templated method in C++11?

I have a templated-method where the return-type is will be the result of a reinterpret_cast<>()-call.
class A {
void *_ptr;
public:
template<typename T>
T buffer() { return reinterpret_cast<T>(_ptr); }
};
This way makes me use the <>-syntax when calling this function:
A a;
auto b = a.buffer<double *>();
I'd prefer to call this method without the template arguments and let the compiler deduce the return type, based on the variable-type.
A a;
double *out = a.buffer();
Is this possible with return-type deduction?
I tried using auto, the->-operand and the trailing return type syntax.
auto buffer() -> decltype(reinterpret_cast<T>(_ptr)) const
{ return reinterpret_cast<T>(_ptr); }
but it still doesn't work.
Is there any way doing this, in C++11?
Yes, but only via a proxy type having a conversion function template:
struct BufferProxy {
void* ptr;
template<class T> operator T*() { return reinterpret_cast<T*>(ptr); }
};
BufferProxy buffer() { return BufferProxy{_ptr}; }
Example.
Note that users who have become familiar with the use of auto for return type deduction are likely to become confused by this technique:
auto out = a.buffer(); // out is BufferProxy
auto* out = a.buffer(); // fails to compile; can't deduce 'auto*' from 'a.A::buffer()'
Up until C++17, you can prevent auto out = a.buffer(); from compiling by giving BufferProxy a deleted copy constructor (and perhaps returning it by aggregate construction: return {_ptr};), but the user could still use auto&& and from C++17 guaranteed copy elision will make the auto form work again.
You may want a class something like the following. This would seem to offer most of what you want to do.
One issue I was wondering about was how to determine if a pointer stored into the class was the same type or not. So I thought it would be best to add an additional method to check the typeid() using the hash_code() method.
So the class I came up with using the operator idea of #ecatmur in his/her answer:
class A {
void *_ptr;
size_t _ptrHash;
public:
template<typename T> operator T*() { return reinterpret_cast<T *>(_ptr); }
template<typename T>
void SetPtr(T *p) { _ptr = p; _ptrHash = typeid(*p).hash_code(); }
template<typename T> bool operator == (T *p) { return p && typeid(*p).hash_code() == _ptrHash /* && p == _ptr */; }
};
The equality operator could either check only the type as above or if you uncomment the additional check, also check for value of the pointer. You probably just want to check for the type.
A simple demo function that I used to test this out was as follows:
void funky1() {
A a;
double ddd[50] = { 0.0 };
ddd[0] = 5.0; ddd[2] = 7.0;
a.SetPtr(&ddd[0]);
double *p = a;
bool bb = a == p;
long lll[50] = { 0 };
lll[0] = 5; lll[2] = 7;
long *q = a;
bb = a == q;
a.SetPtr(&lll[0]);
q = a;
bb = a == q;
}
I stepped through this with the debugger, Visual Studio 2013, and it looked like it worked like a champ.
I guess this answer is the most elegant.
Anyway, you can also let the class initializes your pointer as it follows:
class A {
void *_ptr;
public:
template<typename T>
void buffer(T **t) { *t = reinterpret_cast<T*>(_ptr); }
};
int main() {
A a;
double *b;
a.buffer(&b);
}
This way the type is deduced from the parameter list and you have not to explicitly specify it.

lambda return in initializer list

Let's see a real life example:
class RuleNameConverter {
public:
RuleNameConverter(const boost::property_tree::ptree& pt);
int toIdentifier(const std::string& name) const;
std::string toName(const int id) const;
private:
using Bimap = boost::bimap<std::string, int>;
Bimap bimap_;
};
Where the constructor is this:
RuleNameConverter::RuleNameConverter(const boost::property_tree::ptree& pt) {
for (const auto& item : pt) {
if (item.first == "rule") {
auto name = item.second.get < std::string > ("<xmlattr>.name");
auto id = item.second.get<int>("<xmlattr>.id");
bimap_.insert(Bimap::value_type { name, id });
}
}
}
Assume you want a const member attribute:
...
const Bimap bimap_;
};
You must initialize it in the initializer list, not in the constructor body. It's initialization is non trivial, so you must delegate a function to compute its value. You can use the value returned by a lambda, taking advantages of the move semantics (no copy of temporary objects):
RuleNameConverter::RuleNameConverter(const boost::property_tree::ptree& pt) :
bimap_ { [&pt]() {
Bimap results;
for (const auto& item : pt) {
if (item.first == "rule") {
auto name = item.second.get < std::string > ("<xmlattr>.name");
auto id = item.second.get<int>("<xmlattr>.id");
results.insert(Bimap::value_type {name, id});
}
}
return results;
}() } {
}
Are there any drawbacks to using this technique? Is it worth the trouble? I find it slightly less readable, but what about performance?
Performance-wise, it should not matter all that much. You don't copy around any Bitmap objects, and the construction of your lambda should not take any noticeable time.
But for readability, I would create a static member function instead of a lambda here:
class RuleNameConverter {
public:
RuleNameConverter(const boost::property_tree::ptree& pt);
private:
static Bitmap createBitmap(const boost::property_tree::ptree& pt);
};
RuleNameConverter::RuleNameConverter(const boost::property_tree::ptree& pt) :
bimap_ { createBitmap(pt) } {
}
Bitmap RuleNameConverter::createBitmap(const boost::property_tree::ptree& pt) {
Bimap results;
for (const auto& item : pt) {
if (item.first == "rule") {
auto name = item.second.get < std::string > ("<xmlattr>.name");
auto id = item.second.get<int>("<xmlattr>.id");
results.insert(Bimap::value_type {name, id});
}
}
return results;
}
When you need to initialise several members using helper functions, creating a new lambda for each member leads to an unmaintainable mess in the constructor initialiser list, but several helper functions don't need to have that problem. Additionally, if you add constructor overloads, createBitmap can be easily called from multiple constructors.
Alternatively, use a regular non-member function if the body of createBitmap is not really specific to your RuleNameConverter.
You could wrap the Bimap in another class, where its constructor would have the exact same body as the lambda.
I can't see how using a lambda to avoid a superficial class in this case would lead to any problems, except its intent is perhaps less clear, because it doesn't have a name (but that's the case with pretty much any lambda).

Follow-up: Removing an item from an std:: vector

In the 1st code snippet below, I am trying to remove an element from a vector within a member function based on a static condition function fed into std::remove_if function. My problem here is that the input parameter uuid in removeVipAddress method cannot accessed within the condition function. What do you think I should do here to enable removal of an item from the vector based on the input parameter named uuid? Thanks. NOte: This is a follow up problem explained previously in Removing an item from an std:: vector
SNIPPET 1 (CODE)
void removeVipAddress(std::string &uuid)
{
struct RemoveCond
{
static bool condition(const VipAddressEntity & o)
{
return o.getUUID() == uuid;
}
};
std::vector<VipAddressEntity>::iterator last =
std::remove_if(
mVipAddressList.begin(),
mVipAddressList.end(),
RemoveCond::condition);
mVipAddressList.erase(last, mVipAddressList.end());
}
SNIPPET 2 (COMPILATION OUTPUT)
$ g++ -g -c -std=c++11 -Wall Entity.hpp
Entity.hpp: In static member function ‘static bool ECLBCP::VipAddressSet::removeVipAddress(std::string&)::RemoveCond::condition(const ECLBCP::VipAddressEntity&)’:
Entity.hpp:203:32: error: use of parameter from containing function
Entity.hpp:197:7: error: ‘std::string& uuid’ declared here
If you're using C++11 this could be done with a lambda:
auto last = std::remove_if(
mVipAddressList.begin(),
mVipAddressList.end(),
[uuid]( const VipAddressEntity& o ){
return o.getUUID() == uuid;
});
The last parameter on that function call declares a lambda, which is an anonymous inline function. The [uuid] bit tells it to include uuid in the scope of the lambda.
There's a tutorial on lambdas here
Alternatively you probably want to provide a constructor & member function to your RemoveCond predicate (and implement it using operator() rather than a function named condition).
Something like this:
struct RemoveCond
{
RemoveCond( const std::string& uuid ) :
m_uuid( uuid )
{
}
bool operator()(const VipAddressEntity & o)
{
return o.getUUID() == m_uuid;
}
const std::string& m_uuid;
};
std::remove_if(
mVipAddressList.begin(),
mVipAddressList.end(),
RemoveCond( uuid );
);
If you don't have C++11 lambdas, you could express your RemoveCond as a functor:
struct RemoveCond
{
RemoveCond(const std::string uuid) : uuid_(uuid) {}
bool operator()(const VipAddressEntity & o) const
{
return o.getUUID() == uuid_;
}
const std::string& uuid_;
};
then pass an instance to std::remove_if:
std::remove_if(mVipAddressList.begin(),
mVipAddressList.end(),
RemoveCond(uuid));
BTW you removeVipAddress function should take a const reference:
void removeVipAddress(const std::string &uuid)

remove any element of vector<std::function<...>> that bound to member function

how to remove function that bound to member function of this object :
std::vector<std::function<void(int)>> callbacks;
class MyClass {
public:
MyClass() {
callbacks.push_back(
std::bind(&MyClass::myFunc,this,std::placeholders::_1)
);
}
~MyClass() {
auto it = std::remove_if( std::begin(callbacks),
std::end(callbacks),
[&](std::function<void(int)>& f) {
return // <-- this is my question
// true (remove) if f is bound to member function
// of this
});
callbacks.erase(it,std::end(callbacks));
}
void myFunc(int param){...}
};
typedef decltype(std::bind(&MyClass::myFunc,this,std::placeholders::_1)) bound_type;
auto it = std::remove_if( std::begin(callbacks),
std::end(callbacks),
[](const std::function<void(int)>& f) {
return f.target<bound_type>() != nullptr;
});
The member function template std::function::target<T> returns a pointer to the target object if it is of type T, otherwise it returns null. So you just need to be able to name the type of the target object, which you can get from decltype. Pretty simple really :-)
N.B. that will remove any callbacks of that type, not only ones that have bound the this pointer for the specific object being destroyed. If you are trying to prevent invoking callbacks on an object after it has been destroyed and have no possible way to identify which elements of the vector refer to which objects, you could consider putting a shared_ptr in your class, then storing a weak_ptr to it in the callback, which can be used to detect if the object has been destroyed:
class MyClass
{
struct NullDeleter { void operator()(void*) const { } };
std::shared_ptr<MyClass> sp;
static void safe_invoke(void (MyClass::*f)(int), const std::weak_ptr<MyClass>& wp, int i)
{
if (std::shared_ptr<MyClass> safe_this = wp.lock())
(safe_this.get()->*f)(i);
}
public:
MyClass() : sp(this, NullDeleter()) {
callbacks.push_back(
std::bind(safe_invoke, &MyClass::myFunc ,std::weak_ptr<MyClass>(sp),
std::placeholders::_1)
);
};
This wraps the call to the member function with the invoke function that converts the weak_ptr to a shared_ptr before calling the member function. If the object has been destroyed the shared_ptr will be empty, so the function does nothing. This doesn't actually remove the callback when it becomes invalid, but does make it safe to call.
You can't in the general case without a buttload of extra work. Type erasure clears this information from the object, and std::function does not expose this information directly.
Your specific example may only have one member function that could be the candidate to remove, but what about a class with 5 members that could be stored as callbacks? You'll need to test for all of them, and it's also possible to bind member functions using a lambda, which is pretty much undetectable.
Here's one solution if:
all callbacks are registered from within MyClass
the container is amended to store extra information
you're willing to do all the extra bookkeeping
std::vector<std::pair<std::function<void(int)>, void*>> callbacks;
class MyClass{
static unsigned const num_possible_callbacks = 2; // keep updated
std::array<std::type_info const*, num_possible_callbacks> _infos;
unsigned _next_info;
// adds type_info and passes through
template<class T>
T const& add_info(T const& bound){
if(_next_info == num_possible_callbacks)
throw "oh shi...!"; // something went out of sync
_infos[_next_info++] = &typeid(T);
return bound;
}
public:
MyClass() : _next_info(0){
using std::placeholders::_1;
callbacks.push_back(std::make_pair(
add_info(std::bind(&MyClass::myFunc, this, _1)),
(void*)this));
callbacks.push_back(std::make_pair(
add_info([this](int i){ return myOtherFunc(i, 0.5); }),
(void*)this));
}
~MyClass(){
using std::placeholders::_1;
callbacks.erase(std::remove_if(callbacks.begin(), callbacks.end(),
[&](std::pair<std::function<void(int)>, void*> const& p) -> bool{
if(p.second != (void*)this)
return false;
auto const& f = p.first;
for(unsigned i = 0; i < _infos.size(); ++i)
if(_infos[i] == &f.target_type())
return true;
return false;
}), callbacks.end());
}
void myFunc(int param){ /* ... */ }
void myOtherFunc(int param1, double param2){ /* ... */ }
};
Live example on Ideone.
I once needed to do something like this and I solved it by storing a vector of shared pointers of objects in the class that contain the function and remove the function from the vector by value when they are destroyed, which also makes this automatic.

Tables of C++ member functions

I need a table that maps codes to C++ member functions. Suppose we have this class:
class foo
{
bool one() const;
bool two() const;
bool call(char*) const;
};
What I want is a table like this:
{
{ “somestring”, one },
{ ”otherstring”, two }
};
So that if I have a foo object f, f.call(”somestring”) would look up “somestring” in the table, call the one() member function, and return the result.
All of the called functions have identical prototypes, i.e., they are const, take no parameters, and return bool.
Is this possible? How?
Yes, it's possible, using pointer to member syntax.
Using the prototypes you supplied, the map would be.
std::map< std::string, bool( foo::*)() const>
It would be called with this syntax
this->*my_map["somestring"]();
That odd-looking ->* operator is for pointer to member functions, which can have some odd considerations, due to inheritance. (It's not just a raw address, as -> would expect)
Since you only need to store members of the same class, with the same arguments and return types, you can use pointer-to-member-functions:
bool foo::call(char const * name) const {
static std::map<std::string, bool (foo::*)() const> table
{
{"one", &foo::one},
{"two", &foo::two}
};
auto entry = table.find(name);
if (entry != table.end()) {
return (this->*(entry->second))();
} else {
return false;
}
}
That uses the new initialisation syntax of C++11. If your compiler doesn't support it, there are various other options. You could initialise the map with a static function:
typedef std::map<std::string, bool (foo::*)() const> table_type;
static table_type table = make_table();
static table_type make_table() {
table_type table;
table["one"] = &foo::one;
table["two"] = &foo::two;
return table;
}
or you could use Boost.Assignment:
static std::map<std::string, bool (foo::*)() const> table =
boost::assign::map_list_of
("one", &foo::one)
("two", &foo::two);
or you could use an array, and find the entry with std::find_if (or a simple for loop if your library doesn't have that yet), or std::binary_search if you make sure the array is sorted.
Yes.
struct foo_method
{
std::string name;
bool (foo::*pfun)() const;
};
foo_method methodTable[] =
{
{ “somestring”, &foo::one },
{ ”otherstring”, &foo::one }
};
void foo::call(const char* name) const
{
size_t size = sizeof(methodTable)/sizeof(*methodTable);
for(size_t i = 0 ; i < size ; ++i)
{
if ( methodTable[i].name == name )
{
bool (foo::*pfun)() const = methodTable[i].pfun;
(this->*pfun)(); //invoke
}
}
}
I would go with boost::function with std::map. Concretely, something like this :
typedef boost::function<bool()> MyFunc;
typedef std::map<std::string, MyFunc> MyFuncMap;
Then, given an instance of MyFuncMap, you could just do map["something"](). Then you could wrap that in a class that overloads operator(). You could use function pointers/references, but I prefer using boost::function because it allows me to bind pointers to member functions (using boost::bind) or use other function objects. You can also test boost::function in conditionals as you would with regular function pointers.
Here is the relevant documentation :
Boost.Function
Boost.Bind
Good luck!
Edit: Regarding your question about the const member and boost::function, here's an example :
#include <boost/function.hpp>
#include <boost/bind.hpp>
typedef boost::function<bool ()> FuncPtr;
struct Test
{
bool test() const
{
std::cout << "yay" << std::endl;
}
};
int main(int argc, char **argv)
{
Test t;
FuncPtr ptr = boost::bind(&Test::test, &t);
ptr();
}
I'd just like to add that a pointer to a member function is meaningless without having an instance of a class on which to call it. The situation you've described accounts for this (and I think you know this), however in other situations, it may be necessary to encapsulate the function pointer with a pointer or reference to the instance to which it corresponds in some sort of functor construct.