I'd like to implement simple database for practice, but I cant find solution for one problem. Let's we have something like:
template <class T> class simpleDB
{
public:
string pathToFile;
void writeToFile();
vector<T> base;
//setter for "base"
//getter for "base"
}
Thing I wish is to call writeToFile() after each square-bracket setter call, so the question is: "How should I write such []setter?".
There are a lot of setter examples on google but none of them avail to call something after returning reference for vector member.
Note that T supposed to be any custom complex struct, ex:
struct point
{
int x,y;
}
Thanks
UPD: as asked, I'd like to use this thing as(I skip part with allocating of first element, since its not a question):
simpleDB<point> db;
db[0].x = 1;
db[0].y = 1;
Create a proxy class with an assignment operator.
template <class T> class simpleDB {
// ...
class Proxy {
simpleDB& db;
size_t i;
Proxy& operator=(T t) {
// If you want to auto-allocate the slot...
if (db.base.size() <= i) db.base.resize(i + 1);
db.base[i] = t;
db.writeToFile();
return *this;
}
T operator*() const { return db.base.at(i); }
};
Proxy operator[](size_t i) { return {*this, i}; }
const Proxy operator[](size_t i) const { return {*this, i}; }
};
Related
I created a ring buffer and I want to import that class to Python using boost. When I am trying to that its getting error.
ring.cpp: In function ‘void init_module_ring()’:
ring.cpp:130:16: error: wrong number of template arguments (1, should be 4)
class_<Ring>("Ring").Please help me. Thanks in Advance.
Here is my code:
#include <boost/python/def.hpp>
#include<iostream>
using namespace std;
using namespace boost::python;
template <class T>
class Ring
{
public:
class iterator;
public:
unsigned int m_size;
unsigned int pos;
T *val;
Ring():
m_size(0),pos(0),val(NULL){};
Ring(int size):m_size(size),pos(0){
val=new T[m_size];
};
Ring(const Ring &other)
{
this->m_size = other.m_size;
this->pos= other.pos;
this->val = other.val;
}
~Ring()
{
delete[] val;
}
void insert(T data)
{
val[pos]= data;
pos++;
if(pos==m_size)
pos=0;
}
void displayall()
{
for(int i =0;i<m_size;i++)
{
cout<<val[i]<<' ';
}
}
iterator begin()
{
return iterator(val);
}
iterator end()
{
return iterator(val + m_size);
}
unsigned int size()
{
return m_size;
}
void check()
{
cout<<val<<' ';
cout<<val+5;
}
};
template<class T>
class Ring<T>::iterator
{
T *it_value;
public:
iterator():it_value(NULL){};
iterator(T *value)
{
it_value = value;
};
iterator(const iterator &other)
{
this->it_value = other.it_value;
}
friend ostream& operator<<(ostream &out,iterator it)
{
out<<*it.it_value;
return out;
}
iterator operator++()
{
it_value +=1;
return (iterator(it_value));
}
iterator operator++(const int x)
{
it_value = it_value+ x+1;
return(iterator(it_value));
}
bool operator==(const iterator &other) const
{
return (*it_value == *(other.it_value));
};
bool operator!=(const iterator &other) const
{
return (!(*this == other));
};
iterator operator*()
{
return *this;
}
void display()
{
cout<<*it_value<<' ';
}
};
BOOST_PYTHON_MODULE(ring)
{
class_<Ring>("Ring")
template <class T>
.def(init<int>())
.def("insert", &Ring::insert)
.def("display_all", &Ring::displayall)
;
}
A template is not a class. You need to instantiate your template (i.e. Ring<int> instead of Ring).
class_<Ring<int>>("IntRing", init<int>())
.def("insert", &Ring<int>::insert)
.def("display_all", &Ring<int>::displayall)
;
Also, the template <class T> part in your original code:
class_<Ring>("Ring")
template <class T> // error
.def(init<int>())
.def("insert", &Ring::insert)
.def("display_all", &Ring::displayall)
;
is a syntax error. It suggests that you expect to be able to bind to the template in a generic manner, which is unfortunately not possible. The reason is that templates are instantiated at compile-time, i.e. the compiler needs to know the exact types the template is going to be used with. If you are interfacing with python, you can't know that in advance, because it be decided at runtime.
Under the hood, Boost.Python generates wrapper functions that take the PyObjects from python and convert them to strongly typed values for your parameters (and your return values back to PyObjects). It can only do it because it knows the types to convert the dynamic values to/from.
The best you can do is creating the class that is not generic but instead operates with python objects.
EDIT: In response to you comment ("error: ‘init’ was not declared in this scope"), I think the problem is that you are only including one Boost.Python header. Either #include <boost/python.hpp> or include all other parts that you need (one is init.hpp).
UPDATE: I revised some place, and now the problem has changed in some way.
I'm writing a C++ class. Like:
class qqq{
map<int,int> core;
//......
int& operator[](int n){return core[n];};
};
int main(){
qqq a;
a[3]=7;a[5]=0;//Case a
int b=a[3];//Case b
return 0;
}
Although case A and case B are calling the same function(overloaded operator), but case a is used as an lvalue while case b is used as a rvalue.
For some reason, I want to have the effect that if 0 is passed to a[5], delete the node 5 in core. Like:
int& operator[](int n){
if(CASE A && THE VALUE PASSED TO IT IS 0)
core.erase(core.find(n));
else
return core[n];
}
Maybe my description is not accurate.
Here is an implementation of the proxy pattern mentioned in the comments.
Personally, I don't use this, my maps are wrapped in classes that don't provide operator[] at all, instead there are functions like .get(key, default) .init(key), .setdefault(key, default), etc. depending on the class.
// This code is C++11 but it's not essential to the problem.
// The current code calls copy constructors more than necessary.
#include <map>
#include <cassert>
template<class K, class V>
struct zero_map
{
struct proxy
{
std::map<K, V> *container;
K key;
operator V()
{
auto it = container->find(key);
if (it == container->end())
return V();
return *it;
}
void operator = (V value)
{
if (value == V())
{
container->erase(key);
}
else
{
// probably should use .insert() and conditionally assign
(*container)[key] = value;
}
}
};
std::map<K, V> _inner;
proxy operator[](K k)
{
return proxy{&_inner, k};
}
};
int main()
{
zero_map<int, int> foo;
assert (foo._inner.size() == 0);
foo[1] = 0;
assert (foo._inner.size() == 0);
foo[0] = 1;
assert (foo._inner.size() == 1);
foo[0] = 0;
assert (foo._inner.size() == 0);
}
As a comment said, use a proxy class.
template<typename T, size_t BadIndex>
class Element{ // please use a more meaningful name
public:
Element(const size_t index): index(index){}
operator T& (){return value;}
operator T const&() const{return value;}
T &operator =(const T &rhs){
if(index != BadIndex)
value = rhs;
return value;
}
operator T const&() const{return value;}
operator T&(){return value;}
private:
T value;
const size_t index;
};
class qqq{
public:
std::map<int, Element<int, 5>> core;
Element<int> &operator [](size_t index){
auto itt = core.find(index);
if(itt == core.end()){
core.emplace(index, index);
itt = core.find(index);
}
return (*itt).second;
}
};
That should work, but 5 will always give you a garbage result.
You have to always return a value which can be used as left value in the assignment expression. Therefore, I suggest to use a garbage int variable. I declared the garbage as static because we need just one instance of this variable and we don't care its value.
For example,
class qqq{
static int garbage;
map<int,int> core;
//......
int& operator[](int n){
if(CASE A && THE VALUE PASSED TO IT IS 0)
return garbage;
else
return core[n];
}
};
However, this solution is confusing in my point of view because the behaviour completely changes according to what you specify in the square brackets. If the value passed in input is incorrect, I would probably thrown an exception.
* EDIT *
I think you are over complicating the problem using the [] operator. You can easily solve your problem by using setter and getters. For example :
int set(int index, int value){
if( value == 0)
core.erase(core.find(index));
else
return core[index];
}
int get(int index) {
return core[index];
}
The [] allows only for returning a reference, you don't know what is the value used in the assignment.
You question is now clear, unfortunately you will have no way to do that is C++. operator[] is not a getter and a setter : it can only return a reference, and that reference is than used for a mere assignement. At the moment the operator returns its reference, you cannot know what value will be used for a assignement, and you can hardly know how the ref will be used.
IMHO what you need is more :
int getCore(int i) {
return core[i];
}
void setCore(int i, int newval) {
if (newval == 0) {
core.erase(core.find(i));
}
else {
core[i] == newval;
}
As an exercise for my personal enlightenment, I implement vector math with expression templates. I want to implement some operations that apply the same unary function to all elements to a vector expression. So far, I do this.
My base vector expression template is implemented like this
template <typename E>
class VectorExpr {
public:
int size() const { return static_cast<E const&>(*this).size(); }
float operator[](int i) const { return static_cast<E const&>(*this)[i]; }
operator E& () { return static_cast<E&>(*this); }
operator E const& () const { return static_cast<const E&>(*this); }
}; // class VectorExpr
Then, an object supposed to be a vector will look like this
class Vector2 : public VectorExpr<Vector2> {
public:
inline size_t size() const { return 2; }
template <typename E>
inline Vector2(VectorExpr<E> const& inExpr) {
E const& u = inExpr;
for(int i = 0; i < size(); ++i)
mTuple[i] = u[i];
}
private:
float mTuple[2];
};
Let's say I want to apply std::sin to all elements of an expression
template <typename E>
class VectorSin : public VectorExpr<VectorSin<E> > {
E const& mV;
public:
VectorSin(VectorExpr<E> const& inV) : mV(inV) {}
int size() const { return mV.size(); }
float operator [] (int i) const { return std::sin(mV[i]); }
};
Question => If I want to add more functions, I copy-paste what I do for the sin function, for every single function (like cos, sqrt, fabs, and so on). How I can avoid this kind of copy-pasting ? I tried things and figured out I'm still low in template-fu. No boost allowed ^^
template <typename F, typename E>
class VectorFunc : public VectorExpr<VectorFunc<F, E> > {
E const& mV;
public:
VectorSin(VectorExpr<E> const& inV) : mV(inV) {}
int size() const { return mV.size(); }
float operator [] (int i) const { return f(mV[i]); }
// this assumes the Functor f is default constructible, this is
// already not true for &std::sin. Adding the constructor that
// takes f, is left as an exercise ;)
F f;
};
In addition to the answer by pmr, The standard <cmath> functions aren't functors, so you couldn't use them directly to specify unique specialisations of your class - i.e. you wouldn't have a separate template instantiation for std::sin versus std::cos (which is what I gather you're aiming for? correct me if I've misunderstood you on that).
You could create a wrapper in order to map a function pointer to a distinct type, e.g.
#include <iostream>
template< void (*FuncPtr)() > struct Func2Type
{
void operator() () { FuncPtr(); }
};
void Hello() { std::cout << "Hello" << std::endl; }
void World() { std::cout << "world" << std::endl; }
int main()
{
Func2Type<Hello> test1;
Func2Type<World> test2;
test1();
test2();
}
That way you could use them as template arguments in the same way as a normal functor class
I want to breakup a class so that its decoupled from the logic of performing certain task so that users can write new strategies as they wish to without interfering with the central model. So, I want to use templated strategy class but without having to have the user of the strategy to be templatised:
class Model {
...
boost::shared_ptr< Strategy < T > > m_pStrategy;
...
public:
template < typename T >
void DoSomething() { m_pStrategy < T > ::DoSomething(); }
};
I would like the DoSomething function to not be templated. Is there any other way I can achieve what I want to do here?
thanks.
It seems to me like what you want to implement is a Policy-Based Design. I'm not sure what Model and Strategy do exactly, but it seems like Model is the root class, and Strategy is the Policy class, which users would want to provide in some cases to perform special handling. It also seems like the only reason you keep a pointer to the Strategy<T> object around is so that you can call functions on it.
In this case, you can design your class like this:
template<class Strategy>
class Model : public Strategy {
public:
void DoSomething()
{
// magic happens (we will fill this in shortly)
};
};
You call methods on the Strategy class to do your magic. By letting the users define their own Strategy class, you give them the opportunity to define their own "magic". You need to apply rules on what method the Strategy class will provide at a minimum, so that you can call those methods in Model.
For example, suppose Model is actually some kind of resource manager, capable of being a simple smart pointer, or something else like a resource manager for a Windows Critical Section. Let's rename Model to auto_resource and Strategy will become release_policy and will be responsible for releasing whatever resource was assigned to it. In that case, you might have:
class pointer_release_policy
{
public:
template<class Object> void release(Object* obj) { delete obj; }
};
template<class Managed, class release_policy>
class auto_resource : public release_policy
{
public:
// ... ctors etc defined here
~auto_resource()
{
release_policy::release(managed_);
}
private:
Managed managed_;
};
Which you could use for std::string pointers like this:
typedef auto_resource<std::string*, pointer_release_policy> string_ptr;
string_ptr my_str;
...and when my_str falls off the stack, the release method will automatically be called.
Later you want to add a new policy for releasing Windows mutex HANDLEs:
class handle_release_policy
{
public:
template<class Handle> void release(Handle h)
{
CloseHandle(h); // this is a WINAPI function that deallocates the specified resource
};
};
You can use this thusly:
typedef auto_resource<HANDLE, handle_resource_policy> handle_resource;
//... allocate & use the mutex...
handle_resource mutex = CreateMutex(0, 0, 0);
Of course, in order to flesh all this out you need to add functionality for assigning, copying, releasing etc the resources. Here is a complete working example that puts everything together. I've provided 2 sets of policies, one for Windows CRITICAL_SECTIONs, and another for SOCKETs:
class SimpleCopyPolicy
{
public:
template<class Resource> Resource copy(const Resource& rhs) const { Resource ret = rhs; return ret; }
protected:
~SimpleCopyPolicy(){};
};
class CritsecReleasePolicy
{
public:
template<class Handle> bool release(Handle& h)
{
DeleteCriticalSection(&h);
return true;
}
protected:
~CritsecReleasePolicy() {};
};
class CritsecLockPolicy // CRITICAL_SECTION lock/unlock policies
{
public:
template<class Handle> bool lock(Handle& h)
{
EnterCriticalSection(const_cast<CRITICAL_SECTION*>(&h));
return true;
}
template<class Handle> bool unlock(Handle& h)
{
LeaveCriticalSection(&h);
return true;
}
};
class SocketReleasePolicy
{
public:
template<class Handle> bool release(Handle h) { return 0 != closesocket(h); }
protected:
~SocketReleasePolicy(){};
};
template<class Resource, typename ReleasePolicy, typename CopyPolicy = SimpleCopyPolicy>
class simple_auto_resource : public ReleasePolicy, public CopyPolicy
{
public:
typedef simple_auto_resource<Resource,ReleasePolicy,CopyPolicy> base_type;
simple_auto_resource() : res(0) {}
simple_auto_resource(const Resource & r) : res(copy(r)) {}
~simple_auto_resource() { if(res) release(res); }
void clear() { if(res) release(res); res = 0; }
Resource& get() { return res; }
const Resource& get() const { return res; }
Resource detach() { Resource ret = res; res = 0; return ret; }
operator const Resource&() const { return get(); }
operator Resource&() { return get(); }
base_type& operator=(const Resource& rhs) { clear(); res = copy(rhs); return * this; }
template<class Comp> bool operator==(const Comp& rhs) const { return res == (Resource)rhs; }
template<class Comp> bool operator!=(const Comp& rhs) const { return res != (Resource)rhs; }
template<class Comp> bool operator<(const Comp& rhs) const { return res < (Resource)rhs; }
private:
Resource res;
};
typedef simple_auto_resource<CRITICAL_SECTION, CritsecReleasePolicy> auto_critsec;
typedef simple_auto_resource<SOCKET,SocketReleasePolicy> auto_socket;
For more on policy-based design, see Modern C++ Design.
...
Move the function out of class Strategy<T>.
I need to create a generic object carrier class. I came up with something simple like
template<typename T>
class ObjectCarrier
{
public:
const T& item() const
{
return item_;
}
void setItem(T& item)
{
item_ = item;
}
private:
T item_;
};
This works well when T has got a default constructor (parameterless). Things gets complicated when T has parameterized constructors. So I rewrote the class like
template<typename T>
class ObjectCarrier
{
public:
const T& item() const
{
return *item_;
}
void setItem(T& item)
{
item_ = new T ( item );
}
private:
T* item_;
};
Changed the item_ variable to T* and created a new instance using the copy constructor of T. Again this worked well until T is a pointer type. I mean ObjectCarrier<Foo*> won't work.
I am wondering how can I design this class so that it works for almost all kind of types. I think I may need to create a traits type specialized for pointers. But unfortunately, I am not able to make that work.
Any help would be great.
The above approaches are way way too complicated. Keep it simple, and just solve the constructor arg problem by using template constructors. Don't use pointers, they will create object lifetime and copying headaches.
Here's an implementation I use a lot. The template constructors will forward arguments for things directly on to the nested object which is convenient. The operator T& values let you pass carrier<T> to functions that take a type T, without expensive copying. You can wrap objects that take up to two arguments with this code.
/* A wrapper of type T */
template <typename T>
struct carrier {
carrier() {}
template <typename A1> carrier(const A1& a1) : value(a1) {}
template <typename A1, typename A2> carrier(const A1& a1, const A2& a2) : value(a1, a2) {}
operator T&() { return value; }
operator const T&() const { return value; }
T value;
};
You can use it like this:
const carrier<point> p1(10,10); // make p1 const to stop people changing it
showPoint(p1); // calls a function that expects a point,
showPoint(p1.value); // access the point directly
You can use template specialization for the T* type and rewrite the methods to suite pointers. You can do something like:
template<typename T>
class ObjectCarrier<T*>
{
public:
const T* item() const
{
return item_;
}
void setItem(T* item)
{
item_ = item;
}
private:
T* item_;
};
There is a design patern that is possibly relevant to this - Memento.
A bit off topic, but bear in mind that as soon as you start newing objects up inside your class, you'll need a way to manage the memory. I'd suggest using an std::auto_ptr at the least. You'll also need to provide a copy constructor and an assignment operator, when using std::auto_ptr.
It might be possible to hold the object by value and still defer its construction with the use of placement new and something like the following:
#include <iostream>
#include <cassert>
template <class T>
class ObjectCarrier
{
public:
ObjectCarrier(): ref(0) {}
ObjectCarrier(const ObjectCarrier& other): ref(0)
{
set_data(other.ref);
}
~ObjectCarrier()
{
clear();
}
const ObjectCarrier& operator = (const ObjectCarrier& other)
{
if (other.empty())
clear();
else
set_data(other.ref);
return *this;
}
void set(const T& value)
{
set_value(value);
}
const T& get() const
{
assert(!empty() && "No object being carried");
return *ref;
}
bool empty() const
{
return ref == 0;
}
void clear()
{
if (!empty()) {
ref->~T();
ref = 0;
}
}
private:
char data[sizeof(T)];
T* ref;
void set_value(const T& value)
{
if (!empty()) {
*ref = value;
}
else {
ref = new (data) T(value);
}
}
void set_data(const T* value)
{
if (value) {
set_value(*value);
}
}
};
int main()
{
ObjectCarrier<int> i;
ObjectCarrier<int> j(i);
i = j;
i.set(10);
std::cout << i.get() << '\n';
j = i;
i.set(20);
std::cout << i.get() << ' ' << j.get() << ' ' << ObjectCarrier<int>(i).get() << '\n';
}
However, I would somewhat question the usefulness of this class. Perhaps the only purpose it could have, would be to act as Boost.Optional.
But if you don't want the class to be able to not hold a value, just give it a parametrized constructor:
template<typename T>
class ObjectCarrier
{
public:
ObjectCarrier(const T& value = T()):
item_(value)
{
}
const T& item() const
{
return item_;
}
void setItem(T& item)
{
item_ = item;
}
private:
T item_;
};
(It's just that this class seems rather useless, unless perhaps as a facade for code that expects variables to have item and setItem methods, rather than, say, an assignment operator.)
boost::optional does something very similar to this (also boost::any, but nevermind).
You can check out how its implemented at: http://cplusplus.co.il/2009/12/04/boost-optional-and-its-internals/ and don't worry - it's pretty straightforward.