C++ functor and list template - c++

I've implemented a list and iterator templates, the find method is supposed to receive a functor so I declared and implemented one but I keep getting the error that there's no such an object!
"no matching function for call to object of type const findBond "
here's the implementation of the find method:
template <class T>
template <class Predicate>
Iterator<T> List<T> :: find(const Predicate &predicate) {
for (Iterator<T> iterator=begin(); iterator != end(); ++iterator) {
if (predicate(*iterator)) {
return iterator;
}
}
return end();
}
// predicate is a functor that is supposed to return a boolean value
here's the function object:
class findBond{
Bond& bond;
public:
findBond( Bond& bond1) : bond(bond1) {}
bool operator() (Bond& bond1){
return bond==bond1;
}
};
I'm trying to use them here:
void InvestmentBroker :: addBond(const string& name, double value, int amount ){
Bond bond = *new Bond(name, value, amount);
if (bondsDatabase.find(findBond(bond)) != bondsDatabase.end()) {
//throw an exception
} else {
// insert bond to dataBase
}
}
I included the needed files so it's not about the includes
What's wrong? What am I missing here?

Your find method takes a const Predicate& as its argument. That means you can only call const methods of the predicate. However, your functor's call operator is not declared const. You can fix your problem by declaring it const like this:
bool operator() (Bond& bond1) const {/* do stuff */ }
That const at the end of the declaration means that you can't modify this from within the function, which in turn means you can call the function on a const object.

It looks like a constness issue to me - findBond should be const on most arguments.
Change findBond to this
class findBond{
const Bond& bond;
public:
findBond( const Bond& bond1) : bond(bond1) {}
bool operator() const ( const Bond& bond1){
return bond==bond1;
}
};

Related

Defining a proxy-based OutputIterator in terms of boost::iterator_facade

I wrote this C++17 code and expected it to work out of the box.
class putc_iterator : public boost::iterator_facade<
putc_iterator,
void,
std::output_iterator_tag
>
{
friend class boost::iterator_core_access;
struct proxy {
void operator= (char ch) { putc(ch, stdout); }
};
auto dereference() const { return proxy{}; }
void increment() {}
bool equal(const putc_iterator&) const { return false; }
};
I'm trying to match the behavior of all the standard OutputIterators by setting my iterator's member typedefs value_type and reference to void (since those types are meaningless for an iterator whose operator* doesn't return a reference).
However, Boost complains:
In file included from prog.cc:2:
/opt/wandbox/boost-1.63.0/clang-head/include/boost/iterator/iterator_facade.hpp:333:50: error: cannot form a reference to 'void'
static result_type apply(Reference const & x)
^
It looks like Boost is trying to hard-code the generated operator*'s signature as reference operator*() const. That is, boost::iterator_facade could deduce the proper return type of operator*() by simply passing along whatever was returned by dereference(); but for some reason it's just not playing along.
What's the solution? I can't pass proxy as a template parameter of the base class since proxy hasn't been defined yet. I could pull proxy out into a detail namespace:
namespace detail {
struct proxy {
void operator= (char ch) { putc(ch, stdout); }
};
}
class putc_iterator : public boost::iterator_facade<
putc_iterator,
void,
std::output_iterator_tag,
detail::proxy
>
{
friend class boost::iterator_core_access;
auto dereference() const { return detail::proxy{}; }
void increment() {}
bool equal(const putc_iterator&) const { return false; }
};
but that seems awkward and is definitely something that "shouldn't be necessary."
Is this a bug in iterator_facade? Is it a feature-not-a-bug? If the latter, then how am I supposed to use it to create OutputIterators?
Also, a minor nitpick: even my workaround with the detail namespace is "wrong" in the sense that it makes std::is_same_v<putc_iterator::reference, detail::proxy> when what I want (for parity with the standard iterators) is std::is_same_v<putc_iterator::reference, void>.
Boost Iterator Facade was good at the time, but now it is outdated as it is not very flexible (it doesn't play well with auto and with r-value references that in principle can be creating by dereferencing a r-value iterator). I am not againts the facade concept, but it could be upgraded to C++11.
In addition now with C++11 is easier to write iterator from scratch.
Anyway, if you need to define a reference just to comply with the arguments to be passed, (and if you promise not use it) you can use void* instead of void. (Or perhaps for consistency use proxy& and define it outside the class).
class putc_iterator : public boost::iterator_facade<
putc_iterator,
void*,
std::output_iterator_tag
>
{
friend class boost::iterator_core_access;
struct proxy {
void operator= (char ch) { putc(ch, stdout); }
};
auto dereference() const { return proxy{}; }
void increment() {}
bool equal(const putc_iterator&) const { return false; }
};

wrong number of template arguments (3, should be 4)

I tried to use property on c++ to use it instead of too many setter and getter function in data class have lots of member variable.
there are two property class. first one has fixed setter and getter function by default set, get. second one support using custom setter and getter function of its class. below is the code
template <class T>
class Property
{
T data;
public:
// access with function call syntax
Property() : data() { }
T operator()() const
{
return data;
}
T operator()( T const & value)
{
data = value;
return data;
}
// access with get()/set() syntax
T get() const
{
return data;
}
T set( T const & value )
{
data = value;
return data;
}
// access with '=' sign
operator T() const
{
return data;
}
T operator = ( T const & value )
{
data = value;
return data;
}
typedef T value_type; // might be useful for template deductions
};
// a read-write property which invokes user-defined functions
template <class T, class Object, T(Object::*real_getter)(), T(Object::*real_setter)(T const &) >
class RWProperty
{
Object * my_object;
public:
// this function must be called by the containing class, normally in a
// constructor, to initialize the RWProperty so it knows where its
// real implementation code can be found
void operator () ( Object * obj )
{
my_object = obj;
}
// function call syntax
T operator()() const
{
return (my_object->*real_getter)();
}
T operator()( T const & value )
{
return (my_object->*real_setter)( value );
}
// get/set syntax
T get() const
{
return (my_object->*real_getter)();
}
T set( T const & value )
{
return (my_object->*real_setter)( value );
}
// access with '=' sign
operator T() const
{
return (my_object->*real_getter)();
}
T operator = ( T const & value )
{
return (my_object->*real_setter)( value );
}
typedef T value_type; // might be useful for template deductions
};
and i'm testing these properties in OptionSet class before putting it into project code
#include <QString>
class OptionSet
{
public:
explicit OptionSet() {}
Property<QString> m_MeshMode;
RWProperty<uint, OptionSet, &getNumberOfVbo, &setNumberOfVbo> uNumberOfVbo;
// this causes problems
protected:
private:
Property<uint> m_uNumberOfVbo;
uint setNumberOfVbo(const uint& rVboCount)
{
// something to do here
return m_uNumberOfVbo(rVboCount);
}
uint getNumberOfVbo() const
{
return m_uNumberOfVbo();
}
};
but in use RWProperty, even i passed 4 arguments of template like member type, class type has setter and getter function, getter function pointer, setter function pointer in order, it says
"wrong number of template arguments (3, should be 4) :
RWProperty <uint, OptionSet, &getNumberOfVbo, &setNumberOfVbo>
uNumberOfVbo"
"provided for 'template<class T, class Object,
T(Object::*real_getter)(), T(Object::*real_setter)(const T&)> class
RWProperty : class RWProperty"
I guess i'm doing something wrong to pass arguments in template.
is there anyone knows what happened?
There are three mistakes in your code:
Firstly, to get the address of a member function, you need to include the class name:
RWProperty<uint, OptionSet
, &OptionSet::getNumberOfVbo
// ~~~~~~~~~~~^
, &OptionSet::setNumberOfVbo> uNumberOfVbo;
// ~~~~~~~~~~~^
Secondly, to form a pointer to const qualified member function, you need to append const keyword to the declaration of that pointer:
T (Object::*real_getter)() const
// ~~~~^ to match 'uint getNumberOfVbo() const'
Lastly, OptionSet inside OptionSet itself is an incomplete type. You can't refer to its member unless the point of declaration of that member comes first. This basically means you need to reorder your declarations within OptionSet so that setNumberOfVbo and getNumberOfVbo comes before you declare uNumberOfVbo data member:
class OptionSet
{
//...
uint setNumberOfVbo(const uint& rVboCount) { /*...*/ }
uint getNumberOfVbo() const { /*...*/ }
// Ok, now they are known and can be found in the class scope
//...
RWProperty<uint, OptionSet
, &OptionSet::getNumberOfVbo
, &OptionSet::setNumberOfVbo> uNumberOfVbo;
};

how to use overloaded std::less for std::map

I have the following snippet:
typedef char OR[12];
class COR
{
OR m_or;
public:
COR(const char* or) { strcpy(m_or, or); }
COR(const COR& o) { strcpy(m_or, o.m_or); }
const char* GetOR() const { return m_or; }
#if 0 // I do not wish to use this as it will create a temporary object
bool operator<(const COR& left, const COR& right) const
{ return (strcmp(left.m_or, right.m_or) < 0); }
#endif
};
namespace std {
template<>
struct less<COR> {
bool operator()(const COR& cor, const char* or) const
{ return (strcmp(cor.GetOR(), or) < 0); }
};
}
When I try this I get an error:
error: no matching function for call to std::map<COR, SomeStruct*, std::less<COR>, std::allocator<std::pair<const COR, SomeStruct*> > >::find(const char*&)
I do not want to use any method that involves comparison of two "COR" objects. I will have comparison of COR with const char*. Can you guys suggest a way to do it?
Several methods:
Note: None of these generate extra copies as the values are always passed by reference (and since we don't normally mutate an object on comparison pass by const reference).
Method 1:
class COR
{
public:
// 1: Make it a member function
// Thus you only specify the right hand side.
// The left is implicit.
bool operator<(COR const& right) const
{
return (strcmp(m_or, right.m_or) < 0);
}
};
method 2:
class COR
{
public:
// 2: Make it a friend non member function
// Note: Just because I declare it here does not make it part of the class.
// This is a separate non member function
// The compiler makes the destinction because of the `friened`
friend bool operator<(COR const& left, COR const& right)
{
return (strcmp(left.m_or, right.m_or) < 0);
}
};
Method 3:
class COR
{
public:
// Just an example. Just need some way for the functor to access members
// In a way that will allow a strict weak ordering.
bool test(COR const& right) const {return (strcmp(m_or, right.m_or) < 0);}
};
// Define a functor.
// This is just a class with the operator() overloaded so that it can
// act like a function. You can make it do whatever you like but for
// comparisons it will be passed two members of the container (accept by const
// reference and make sure the functor is const member and things will go well).
struct CorTest
{
bool operator()(COR const& left, COR const& right) const
{
return left.test(right);
}
};
// When you declare the set you just pass as the second template parameter.
// (or third if it is a map)
std::set<COR, CorTest> mySet;
std::map<COR, int, CorTest> myMap;
The method you use will depend on situation.
In most situations I would use method (1). If there is a special sort order I needed for a one off event that I want to use with a sorted container then I would use method (3). method (2) can be used as an alternative to method (1) and in some situations is better (but you need to provide more details about usage before I would say use this).
You got this error because you made a mistake - the arguments type of the std::less operator() must be identical. So, this works:
template <>
struct std::less<COR>
{
bool operator()(const COR &a, const COR &b) const { return (strcmp(a.GetOR(), b.GetOR()) < 0); }
};
You're looking for the new overloaded versions of find(), lower_bound(), and upper_bound() added in C++14. They do exactly what you are asking for.
https://en.cppreference.com/w/cpp/container/set/find

Is it possible to set default constructor to `std::map<T1, T2>` values?

So I want to create a simple map std::map<T1, std::string> and I have a function that returns std::string I want somehow to link item creation in std::map with my function so that when my_map[some_new_element] is called my function will be called and its return set to value for some_new_element key. Is such thing possible and how to do it?
You can wrap the map itself or the value type or operator[].
Last wrapper will be the simplest:
template <typename T>
std::string& get_default(std::map<T, std::string>& map, const T& key) {
auto it = map.find(key);
if (it == map.end()) {
return map[key] = create_default_value();
} else {
return *it;
}
}
The value type shouldn't be too hard, either:
struct default_string {
std::string wrapped_string;
default_string() : wrapped_string(create_default_value()) {}
explicit default_string(const std::string& wrapped_string)
: wrapped_string(wrapped_string) {}
operator const std::string&() const { return wrapped_string; }
operator std::string&() { return wrapped_string; }
};
Wrapping map will take a bit more work, as you'd have to duplicate the entire interface, including typedefs. Note: this code is not tested, treat it as proof-of-concept, to steer you in the right direction.
What about a small wrapper class for std::string?
class StringWrapper {
StringWrapper() { //... your code
}
operator std::string&() { return m_string; } // or something like that
private:
std::string m_string;
};
Now you use the following map-type:
std::map<T1, StringWrapper> mymap;
In the constructor of StringWrapper you can define custom actions. It gets called when you insert an item into your map.

Custom STL container wrapper report weird compiler error

I have a C++ library (with over 50 source files) which uses a lot of STL routines with primary containers being list and vector. This has caused a huge code bloat and I would like to reduce the code bloat by creating another library which is essentially a wrapper
over the list and vector.
I basically need a wrapper around std::list which works perfectly for the list container of any type.
Shown below is my list wrapper class.
template<typename T>
class wlist
{
private:
std::list<T> m_list;
public:
wlist();
typedef std::list<void*>::iterator Iterator;
typedef std::list<void*>::const_iterator CIterator;
unsigned int size () { return m_list.size(); }
bool empty () { return m_list.empty(); }
void pop_back () { m_list.pop_back(); }
void pop_front () { m_list.pop_front(); }
void push_front (const T& item) { m_list.push_front(item); }
void push_back (const T& item) { m_list.push_back(item); }
bool delete_item (void* item);
T& back () { return (m_list.empty()) ? NULL : m_list.back();}
T& front () { return (m_list.empty()) ? NULL : m_list.front();}
Iterator erase() { return m_list.erase(); }
Iterator begin() { return (Iterator) m_list.begin(); }
Iterator end() { return (Iterator) m_list.end(); }
};
File1.h:
class label{
public:
int getPosition(void);
setPosition(int x);
private:
wlist<text> _elementText; // used in place of list<text> _elementText;
}
File2.h:
class image {
private:
void draw image() {
//Used instead of list<label*>::iterator currentElement = _elementText.begin();
wlist<label*>::iterator currentElement = _elementText.begin();
currentElement->getPosition(); // Here is the problem.
currentElement ++;
}
}
Invoking getPosition() bombs with the following error message:
error: request for member `getPosition' in `*(&currentElement)->std::_List_iterator<_Tp>::operator-> [with _Tp = void*]()', which is of non-class type `void*'
Type casting getPosition() to label type didn't work. Additionally my iterators are of type void*.
I think the problem is that the line
currentElement->getPosition();
won't work because currentElement is an iterator over void*s, not labels. Since iterators over some type T act like T*s, this means that your currentElement iterator acts like a label**, and so writing the above code is similar to writing
(*currentElement).getPosition();
Here, the problem should be a bit easier to see - *currentElement is a label*, not a label, and so you can't use the dot operator on it.
To fix this, trying changing this code to
((label *)(*currentElement))->getPosition();
This dereferences the iterator and typecasts the void* to get a label*, then uses the arrow operator to call the getPosition() function on the label being pointed at.
Your iterator types seem to be declared in terms of std::list<void*>::iterator. This doesn't sound right to me...