C++ class with template member variable. and parameter memory out - c++

struct PacketBase
{
virtual ~PacketBase() {}
template<class T>
const T& get() const
{
return static_cast<const PacketVal<T>&>(*this).val;
}
template<class T>
void set(const T& rhs)
{
return static_cast<PacketVal<T>>(*this).val = rhs;
}
};
template <typename T>
struct PacketVal : public PacketBase
{
T val;
PacketVal(const T& rhs) : val(rhs) {}
~PacketVal() {}
};
class CResponsePacket
{
private:
std::vector<std::pair<int, const PacketBase*>> m_vPacketData;
public:
void addValue(int n, const PacketBase& packetData)
{
m_vPacketData.emplace_back(std::make_pair(n, &packetData));
}
void print()
{
for ( auto& data : m_vPacketData )
{
std::printf("%d - ", data.first);
std::printf("%s\n", data.second->get<std::string>().c_str());
}
}
};
CResponsePacket has template class member-variable.
int main()
{
CResponsePacket packet;
std::string strAAA("AAA");
PacketVal<std::string> pVal(strAAA);
packet.addValue(1, pVal);
for ( int nIdx = 0; nIdx < 5; ++nIdx )
{
PacketVal<std::string> pp(strAAA);
packet.addValue(nIdx + 1, pp);
}
packet.print();
return 0;
}
The result is
1 - AAA
1 -
2 -
3 -
4 -
5 -
Because the instance is in a loop, memory is destroyed. But this is just an example, and I have to use loop actually. How can I solve this...?
......................
..................

You can make use of std::shared_pointer or std::unique_ptr (depending of your use), and so having the vector looking like this:
std::vector<std::pair<int, std::shared_pointer<PacketBase>>> m_vPacketData;
And so then the addValue method should look like this:
void addValue(int n, const PacketBase& packetData)
{
m_vPacketData.emplace_back(
std::make_pair(
n,
std::make_shared<PacketBase>(packetData)
)
);
}
This will make a copy of packetData on the heap, and store the reference in a shared pointer. If you don't what this copy to be made, then you have to define a new constructor in PacketBase
class PacketBase{
public:
PacketBase(PacketBase&& el): attr(std::move(el.attr))... {...}
}
and then redefining the addValue that accept a rvalue reference
void addValue(int n, PacketBase&& packetData)
{
m_vPacketData.emplace_back(
std::make_pair(
n,
std::make_shared<PacketBase>(std::move(packetData))
)
);
}
And then actually calling the right addValue from main:
for ( int nIdx = 0; nIdx < 5; ++nIdx )
{
PacketVal<std::string> pp(strAAA);
packet.addValue(nIdx + 1, std::move(pp));
}
Or actually just:
for ( int nIdx = 0; nIdx < 5; ++nIdx )
packet.addValue(nIdx + 1, PacketVal<std::string>(strAAA););
This will obviously force you to rewrite the entire class, because you are changing the attribute type... the other way that you can achieve this is switch from
m_vPacketData.emplace_back(std::make_pair(n, &packetData));
to
m_vPacketData.emplace_back(std::make_pair(n, new PacketVal(packetData)));
But you have then remember to delete the objects on the heap or you will have memory leaks

Related

C++ initialization with interface

I am trying to implement a general value class in C++ that can contain integer, float, and fractions, etc. So I wrote an interface value_interface and had int wrapped up in int_wrapper to inherit from the interface.
However, value(3) will not initialize a value object, because even if 3 is convertable to int_wrapper, which is convertable to value_interface, value_interface is not directly convertable to value. Is there a way to make value(3) possible? Or is there a better way to do this?
#include <string>
class value_interface {
public:
virtual std::string to_string() const = 0;
virtual ~value_interface() {}
};
class value {
std::shared_ptr<value_interface> d_ptr_;
public:
value(value_interface* x) { d_ptr_ = std::unique_ptr<value_interface>(x); }
std::string to_string() const { return d_ptr_->to_string(); }
};
class int_wrapper : public value_interface {
int val_;
public:
int_wrapper(const int val) : val_(val) {}
operator int() const { return val_; }
std::string to_string() const override { return std::to_string(val_); }
friend value operator+(int_wrapper x, int_wrapper y);
};
int main() {
value a = 3; // Error C2440 'initializing': cannot convert from 'int' to 'value'
int_wrapper b = 3; // ok
value_interface& c = static_cast<value_interface&>(b); // ok
value d = &c; // ok
return 0;
}
Create a make_value templated function with specialisations for each class. e.g:
template < typename T >
value make_value( const T& t );
template <>
value make_value< int >( const int& i )
{
return value{ std::make_shared< int_wrapper >( i ) };
}
Alternatively you can template the value constructor which will allow you to do value v = 3 directly:
class value {
std::shared_ptr<value_interface> d_ptr_;
public:
value(value_interface* x) { d_ptr_ = std::unique_ptr<value_interface>(x); }
template < typename T >
value( const T& t );
std::string to_string() const { return d_ptr_->to_string(); }
};
template <>
value::value< int >( const int& i )
:d_ptr_(std::make_shared<int_wrapper>(i))
{
}

Overloading operator [ ] for 3 dimension array [duplicate]

Is it possible to overload [] operator twice? To allow, something like this: function[3][3](like in a two dimensional array).
If it is possible, I would like to see some example code.
You can overload operator[] to return an object on which you can use operator[] again to get a result.
class ArrayOfArrays {
public:
ArrayOfArrays() {
_arrayofarrays = new int*[10];
for(int i = 0; i < 10; ++i)
_arrayofarrays[i] = new int[10];
}
class Proxy {
public:
Proxy(int* _array) : _array(_array) { }
int operator[](int index) {
return _array[index];
}
private:
int* _array;
};
Proxy operator[](int index) {
return Proxy(_arrayofarrays[index]);
}
private:
int** _arrayofarrays;
};
Then you can use it like:
ArrayOfArrays aoa;
aoa[3][5];
This is just a simple example, you'd want to add a bunch of bounds checking and stuff, but you get the idea.
For a two dimensional array, specifically, you might get away with a single operator[] overload that returns a pointer to the first element of each row.
Then you can use the built-in indexing operator to access each element within the row.
An expression x[y][z] requires that x[y] evaluates to an object d that supports d[z].
This means that x[y] should be an object with an operator[] that evaluates to a "proxy object" that also supports an operator[].
This is the only way to chain them.
Alternatively, overload operator() to take multiple arguments, such that you might invoke myObject(x,y).
It is possible if you return some kind of proxy class in first [] call. However, there is other option: you can overload operator() that can accept any number of arguments (function(3,3)).
One approach is using std::pair<int,int>:
class Array2D
{
int** m_p2dArray;
public:
int operator[](const std::pair<int,int>& Index)
{
return m_p2dArray[Index.first][Index.second];
}
};
int main()
{
Array2D theArray;
pair<int, int> theIndex(2,3);
int nValue;
nValue = theArray[theIndex];
}
Of course, you may typedef the pair<int,int>
You can use a proxy object, something like this:
#include <iostream>
struct Object
{
struct Proxy
{
Object *mObj;
int mI;
Proxy(Object *obj, int i)
: mObj(obj), mI(i)
{
}
int operator[](int j)
{
return mI * j;
}
};
Proxy operator[](int i)
{
return Proxy(this, i);
}
};
int main()
{
Object o;
std::cout << o[2][3] << std::endl;
}
If, instead of saying a[x][y], you would like to say a[{x,y}], you can do like this:
struct Coordinate { int x, y; }
class Matrix {
int** data;
operator[](Coordinate c) {
return data[c.y][c.x];
}
}
It 'll be great if you can let me know what function, function[x] and function[x][y] are. But anyway let me consider it as an object declared somewhere like
SomeClass function;
(Because you said that it's operator overload, I think you won't be interested at array like SomeClass function[16][32];)
So function is an instance of type SomeClass. Then look up declaration of SomeClass for the return type of operator[] overload, just like
ReturnType operator[](ParamType);
Then function[x] will have the type ReturnType. Again look up ReturnType for the operator[] overload. If there is such a method, you could then use the expression function[x][y].
Note, unlike function(x, y), function[x][y] are 2 separate calls. So it's hard for compiler or runtime garantees the atomicity unless you use a lock in the context. A similar example is, libc says printf is atomic while successively calls to the overloaded operator<< in output stream are not. A statement like
std::cout << "hello" << std::endl;
might have problem in multi-thread application, but something like
printf("%s%s", "hello", "\n");
is fine.
template<class F>
struct indexer_t{
F f;
template<class I>
std::result_of_t<F const&(I)> operator[](I&&i)const{
return f(std::forward<I>(i))1;
}
};
template<class F>
indexer_t<std::decay_t<F>> as_indexer(F&& f){return {std::forward<F>(f)};}
This lets you take a lambda, and produce an indexer (with [] support).
Suppose you have an operator() that supports passing both coordinates at onxe as two arguments. Now writing [][] support is just:
auto operator[](size_t i){
return as_indexer(
[i,this](size_t j)->decltype(auto)
{return (*this)(i,j);}
);
}
auto operator[](size_t i)const{
return as_indexer(
[i,this](size_t j)->decltype(auto)
{return (*this)(i,j);}
);
}
And done. No custom class required.
#include<iostream>
using namespace std;
class Array
{
private: int *p;
public:
int length;
Array(int size = 0): length(size)
{
p=new int(length);
}
int& operator [](const int k)
{
return p[k];
}
};
class Matrix
{
private: Array *p;
public:
int r,c;
Matrix(int i=0, int j=0):r(i), c(j)
{
p= new Array[r];
}
Array& operator [](const int& i)
{
return p[i];
}
};
/*Driver program*/
int main()
{
Matrix M1(3,3); /*for checking purpose*/
M1[2][2]=5;
}
struct test
{
using array_reference = int(&)[32][32];
array_reference operator [] (std::size_t index)
{
return m_data[index];
}
private:
int m_data[32][32][32];
};
Found my own simple solution to this.
vector< vector< T > > or T** is required only when you have rows of variable length
and way too inefficient in terms of memory usage/allocations
if you require rectangular array consider doing some math instead!
see at() method:
template<typename T > class array2d {
protected:
std::vector< T > _dataStore;
size_t _sx;
public:
array2d(size_t sx, size_t sy = 1): _sx(sx), _dataStore(sx*sy) {}
T& at( size_t x, size_t y ) { return _dataStore[ x+y*sx]; }
const T& at( size_t x, size_t y ) const { return _dataStore[ x+y*sx]; }
const T& get( size_t x, size_t y ) const { return at(x,y); }
void set( size_t x, size_t y, const T& newValue ) { at(x,y) = newValue; }
};
The shortest and easiest solution:
class Matrix
{
public:
float m_matrix[4][4];
// for statements like matrix[0][0] = 1;
float* operator [] (int index)
{
return m_matrix[index];
}
// for statements like matrix[0][0] = otherMatrix[0][0];
const float* operator [] (int index) const
{
return m_matrix[index];
}
};
It is possible to overload multiple [] using a specialized template handler. Just to show how it works :
#include <iostream>
#include <algorithm>
#include <numeric>
#include <tuple>
#include <array>
using namespace std;
// the number '3' is the number of [] to overload (fixed at compile time)
struct TestClass : public SubscriptHandler<TestClass,int,int,3> {
// the arguments will be packed in reverse order into a std::array of size 3
// and the last [] will forward them to callSubscript()
int callSubscript(array<int,3>& v) {
return accumulate(v.begin(),v.end(),0);
}
};
int main() {
TestClass a;
cout<<a[3][2][9]; // prints 14 (3+2+9)
return 0;
}
And now the definition of SubscriptHandler<ClassType,ArgType,RetType,N> to make the previous code work. It only shows how it can be done. This solution is optimal nor bug-free (not threadsafe for instance).
#include <iostream>
#include <algorithm>
#include <numeric>
#include <tuple>
#include <array>
using namespace std;
template <typename ClassType,typename ArgType,typename RetType, int N> class SubscriptHandler;
template<typename ClassType,typename ArgType,typename RetType, int N,int Recursion> class SubscriptHandler_ {
ClassType*obj;
array<ArgType,N+1> *arr;
typedef SubscriptHandler_<ClassType,ArgType,RetType,N,Recursion-1> Subtype;
friend class SubscriptHandler_<ClassType,ArgType,RetType,N,Recursion+1>;
friend class SubscriptHandler<ClassType,ArgType,RetType,N+1>;
public:
Subtype operator[](const ArgType& arg){
Subtype s;
s.obj = obj;
s.arr = arr;
arr->at(Recursion)=arg;
return s;
}
};
template<typename ClassType,typename ArgType,typename RetType,int N> class SubscriptHandler_<ClassType,ArgType,RetType,N,0> {
ClassType*obj;
array<ArgType,N+1> *arr;
friend class SubscriptHandler_<ClassType,ArgType,RetType,N,1>;
friend class SubscriptHandler<ClassType,ArgType,RetType,N+1>;
public:
RetType operator[](const ArgType& arg){
arr->at(0) = arg;
return obj->callSubscript(*arr);
}
};
template<typename ClassType,typename ArgType,typename RetType, int N> class SubscriptHandler{
array<ArgType,N> arr;
ClassType*ptr;
typedef SubscriptHandler_<ClassType,ArgType,RetType,N-1,N-2> Subtype;
protected:
SubscriptHandler() {
ptr=(ClassType*)this;
}
public:
Subtype operator[](const ArgType& arg){
Subtype s;
s.arr=&arr;
s.obj=ptr;
s.arr->at(N-1)=arg;
return s;
}
};
template<typename ClassType,typename ArgType,typename RetType> struct SubscriptHandler<ClassType,ArgType,RetType,1>{
RetType operator[](const ArgType&arg) {
array<ArgType,1> arr;
arr.at(0)=arg;
return ((ClassType*)this)->callSubscript(arr);
}
};
With a std::vector<std::vector<type*>>, you can build the inside vector using custom input operator that iterate over your data and return a pointer to each data.
For example:
size_t w, h;
int* myData = retrieveData(&w, &h);
std::vector<std::vector<int*> > data;
data.reserve(w);
template<typename T>
struct myIterator : public std::iterator<std::input_iterator_tag, T*>
{
myIterator(T* data) :
_data(data)
{}
T* _data;
bool operator==(const myIterator& rhs){return rhs.data == data;}
bool operator!=(const myIterator& rhs){return rhs.data != data;}
T* operator*(){return data;}
T* operator->(){return data;}
myIterator& operator++(){data = &data[1]; return *this; }
};
for (size_t i = 0; i < w; ++i)
{
data.push_back(std::vector<int*>(myIterator<int>(&myData[i * h]),
myIterator<int>(&myData[(i + 1) * h])));
}
Live example
This solution has the advantage of providing you with a real STL container, so you can use special for loops, STL algorithms, and so on.
for (size_t i = 0; i < w; ++i)
for (size_t j = 0; j < h; ++j)
std::cout << *data[i][j] << std::endl;
However, it does create vectors of pointers, so if you're using small datastructures such as this one you can directly copy the content inside the array.
Sample code:
template<class T>
class Array2D
{
public:
Array2D(int a, int b)
{
num1 = (T**)new int [a*sizeof(int*)];
for(int i = 0; i < a; i++)
num1[i] = new int [b*sizeof(int)];
for (int i = 0; i < a; i++) {
for (int j = 0; j < b; j++) {
num1[i][j] = i*j;
}
}
}
class Array1D
{
public:
Array1D(int* a):temp(a) {}
T& operator[](int a)
{
return temp[a];
}
T* temp;
};
T** num1;
Array1D operator[] (int a)
{
return Array1D(num1[a]);
}
};
int _tmain(int argc, _TCHAR* argv[])
{
Array2D<int> arr(20, 30);
std::cout << arr[2][3];
getchar();
return 0;
}
Using C++11 and the Standard Library you can make a very nice two-dimensional array in a single line of code:
std::array<std::array<int, columnCount>, rowCount> myMatrix {0};
std::array<std::array<std::string, columnCount>, rowCount> myStringMatrix;
std::array<std::array<Widget, columnCount>, rowCount> myWidgetMatrix;
By deciding the inner matrix represents rows, you access the matrix with an myMatrix[y][x] syntax:
myMatrix[0][0] = 1;
myMatrix[0][3] = 2;
myMatrix[3][4] = 3;
std::cout << myMatrix[3][4]; // outputs 3
myStringMatrix[2][4] = "foo";
myWidgetMatrix[1][5].doTheStuff();
And you can use ranged-for for output:
for (const auto &row : myMatrix) {
for (const auto &elem : row) {
std::cout << elem << " ";
}
std::cout << std::endl;
}
(Deciding the inner array represents columns would allow for an foo[x][y] syntax but you'd need to use clumsier for(;;) loops to display output.)

Abstract base class for Scalar, Vector, Tensor,

I want to design a class PrimitiveType which serves as an abstract class for mathematical entities such as scalar, vector, tensor, and so on to store them in a std::vector<PrimitiveType *> myVector through which I can iterate. For example, having two of these vectors of identical size, say myVector1 and myVector2, I want to be able to do something like
for (size_t i = 0; i < myVector1.size(); i++)
myVector1[i] += myVector2[i];
and don't want to care whether I'm adding scalars, vectors, or tensors. Up to now, I came up with
#include <algorithm>
#include <cstddef>
#include <iostream>
template<class T> class Scalar;
template<class T>
class PrimitiveType
{
protected:
size_t size_;
T *value_;
public:
virtual ~PrimitiveType() = 0;
PrimitiveType & operator+=(const PrimitiveType &primitiveType)
{
for (size_t i = 0; i < size_; i++)
value_[i] += primitiveType.value_[i];
return *this;
}
};
template<class T> PrimitiveType<T>::~PrimitiveType() {};
template<class T>
class Scalar : public PrimitiveType<T>
{
using PrimitiveType<T>::size_;
using PrimitiveType<T>::value_;
public:
Scalar(T value = 0.0)
{
size_ = 1;
value_ = new T(value);
}
~Scalar() { delete value_; }
operator T &() { return *value_; }
};
template<class T>
class Vector : public PrimitiveType<T>
{
using PrimitiveType<T>::size_;
using PrimitiveType<T>::value_;
public:
Vector(T value = 0.0)
{
size_ = 3;
value_ = new T[size_];
std::fill(value_, size_, value);
}
~Vector() { delete[] value_; }
T & operator()(size_t index) { return value_[index]; }
};
int main()
{
Scalar<double> s(3.2);
std::cout << s << std::endl;
static const size_t size = 3;
std::vector<PrimitiveType<double> *> p = std::vector<PrimitiveType<double> *>(size);
for (size_t i = 0; i < size; i++)
{
p[i] = new Scalar<double>();
*(p[i]) += s;
std::cout << *static_cast<Scalar<double> *>(p[i]) << std::endl;
}
}
but I don't think this is a very clean solution. In particular,
1) I would like to be able to use initializer lists in the child classes but get problems with dependent name lookup, e.g.
error: ‘using PrimitiveType::size_’ is not a non-static data member of ‘Scalar’
How to realize something like Scalar(T value = 0.0) : size_(1) , value_(new T(value)) {}?
2) I would actually prefer to make value_ a static array because I know at compile time what size value_ has for Scalar, Vector, ... Of course, this does not hold for PrimitiveType, however, an instance of PrimitiveType gets never created.
Edit: Complete edit because other solution was not ok.
Well, the simplest way for your problem would be to move the storage from the main class to the base class and provide accessor of element:
template <class C>
class PrimitiveType {
public:
PrimitiveType & operator+=(const PrimitiveType &primitiveType) {
if (this->_size() != primitiveType._size()) {
throw "Incompatible type." ;
}
for (size_t i = 0 ; i < this->_size() ; ++i) {
this->_get(i) += primitiveType._get(i) ;
}
return *this ;
}
protected:
virtual C& _get (size_t) = 0 ;
virtual C _get(size_t) const = 0 ;
virtual size_t _size () const = 0 ;
};
Then in Scalar and Vector for example:
template <class C>
class Scalar : PrimitiveType <C> {
C _value ;
public:
Scalar (C const& c) : _value(c) { }
protected:
virtual C& _get (size_t) = 0 { return _value ; }
virtual C _get(size_t) const = 0 { return _value ; }
virtual size_t _size () const = 0 { return 1 ; }
};
template <class C, int N = 3>
class Vector : PrimitiveType <C> {
std::array <C, N> _values ;
public:
Scalar (std::initializer_list <C> l) : _values(l) { }
protected:
virtual C& _get (size_t i) = 0 { return _values(i) ; }
virtual C _get(size_t i) const = 0 { return _values(i) ; }
virtual size_t _size () const = 0 { return _values.size() ; }
};
End of edit.
For your first question, just add a protected constructor in PrimitiveType and call it from your child class:
class PrimitiveType {
protected:
PrimitiveType (/* */) : _values(/* */), /* ... */ { }
};
class Scalar {
public:
Scalar (/* */) : PrimitiveType(/* */) { }
}
For your second questions, add a storage type as second argument templates of primitive type:
template <class C, class S = std::vector <C>>
class PrimitiveType { /* */ }
template <class C>
class Scalar : public PrimitiveType <C, std::array <C, 1>> { /* */ }
Detailled example:
template <class C, class S = std::vector <C>>
class PrimitiveType {
public:
PrimitiveType & operator+=(const PrimitiveType &primitiveType) {
/** Same code as yours. **/
}
protected:
S _values ;
PrimitiveType (std::initializer_list <C> l) : _values(l) { }
};
template <class C>
class Scalar : public PrimitiveType <C, std::array <C, 1>> {
public:
Scalar (C const& c) : PrimitiveType({c}) { }
};

c++: Performance increase on non-template delegate class

This is a simple delegate class that only works for methods of the format void ClassType::MethodType( InputType& ), but can easily be expanded to more generic functions, not shown simply because it would be too large.
class Delegate
{
public:
Delegate( void ) : Object( NULL ), Argument( NULL ) { }
virtual ~Delegate( void ) { }
template <class ClassType, class InputType, void (ClassType::*MethodType)( InputType )>
void Create( ClassType* SetObject, void* SetArgument = NULL )
{
Object = SetObject;
Argument = SetArgument;
StaticCall = &CallMethod<ClassType, InputType, MethodType>;
}
template <class InputType>
inline void operator()( InputType InputValue ) const
{
(*StaticCall)( Object, static_cast<void*>(InputValue) );
}
inline void operator()( void ) const
{
(*StaticCall)( Object, Argument );
}
protected:
typedef void (*FunctionCallType)( void*, void* );
void* Object;
void* Argument;
FunctionCallType StaticCall;
private:
template <class ClassType, class InputType, void (ClassType::*MethodType)( InputType )>
static inline void CallMethod( void* SetObject, void* PassArgument )
{
(static_cast<ClassType*>( SetObject )->*MethodType)( static_cast<InputType>(PassArgument) );
}
};
It's flexible and can be used to pool callback classes, but one problem I have with it is that so far it's on par with (or even slower when used in large vectors like I plan to) than a virtual call if it's used as a base class. I'm looking for any suggestions on how to increase performance since I'm out of ideas, even if it affects functionality.
The simplest performance measuring code I used (with -O3) was:
class VirtualBase
{
public:
virtual void TestCall( int* Data ) {}
};
class VirtualTest : public VirtualBase
{
public:
VirtualTest() : Value(0) {}
void TestCall( int* Data )
{
Value += *Data;
}
private:
int Value;
};
class DelTest : public Delegate
{
public:
DelTest() : Value(0)
{
Create<DelTest, int*, &DelTest::TestCall>( this );
}
void TestCall( int* Data )
{
Value += *Data;
}
private:
int Value;
};
int main( int argc, char **argv )
{
clock_t start;
int Value = 1;
VirtualBase* NewBase = new VirtualTest;
start = clock();
for( size_t Index = 0; Index < 1000000000; ++Index )
{
NewBase->TestCall( &Value );
}
delete NewBase;
std::cout << (( std::clock() - start ) / (double)CLOCKS_PER_SEC) << std::endl;
Delegate* NewDBase = new DelTest;
start = clock();
for( size_t Index = 0; Index < 1000000000; ++Index )
{
NewDBase->operator()( &Value );
}
delete NewDBase;
std::cout << (( std::clock() - start ) / (double)CLOCKS_PER_SEC) << std::endl;
return 0;
}
I should mention that I'd like the class to stay non-template, as it makes classes using callbacks to anything easy to iterate through in a single vector.
You might want to look at this Lightweight Generic C++ Callbacks article on CodeProject
Some of the code from the linked article, showing the use of a function template to do the forwarding:
template<typename R, typename P1, typename P2>
class Callback
{
public:
typedef R (*FuncType)(void*, P1, P2);
Callback() : func(0), obj(0) {}
Callback(FuncType f, void* o) : func(f), obj(o) {}
R operator()(P1 a1, P2 a2)
{
return (*func)(obj, a1, a2);
}
private:
FuncType func;
void* obj;
};
template<typename R, class T, typename P1, typename P2, R (T::*Func)(P1, P2)>
R Wrapper(void* o, P1 a1, P2 a2)
{
return (static_cast<T*>(o)->*Func)(a1, a2);
}
class Foo
{
public:
float Average(int n1, int n2)
{
return (n1 + n2) / 2.0f;
}
};
float Calculate(int n1, int n2, Callback<float, int, int> callback)
{
return callback(n1, n2);
}
int main()
{
Foo f;
Callback<float, int, int> cb
(&Wrapper<float, Foo, int, int, &Foo::Average>, &f);
float result = Calculate(50, 100, cb);
// result == 75.0f
return 0;
}
There is also a great write up on stackoverflow here which will give you better insight.

How to implement pop for a stack as an array program?

Hi I am having trouble implementing a simple pop function for a stack as an array program. The code is below and I am not sure how to fix it.
I am not sure about all the possible cases, so if you could just advise me then I would greatly appreciate!
#include "Exception.h"
template <typename Type>
class Drop_off_stack_as_array {
private:
int itop;
int ibottom;
int entry_count;
int array_capacity;
Type *array;
public:
Drop_off_stack_as_array( int = 10 );
Drop_off_stack_as_array( Drop_off_stack_as_array const & );
~Drop_off_stack_as_array();
int size() const;
bool empty() const;
Type top() const;
bool full() const;
void swap( Drop_off_stack_as_array & );
Drop_off_stack_as_array &operator = ( Drop_off_stack_as_array );
void push( Type const & );
Type pop();
void clear();
// Friends
template <typename T>
friend std::ostream &operator << ( std::ostream &, Drop_off_stack_as_array<T> const & );
};
template <typename Type>
Drop_off_stack_as_array<Type>::Drop_off_stack_as_array( int n ):
itop(0),
ibottom(0),
entry_count(0),
array_capacity(n),
array(new Type[array_capacity]){
//empty constructor
}
template <typename Type>
Drop_off_stack_as_array<Type>::Drop_off_stack_as_array( Drop_off_stack_as_array<Type> const &stack ):
itop( stack.itop ),
ibottom( stack.ibottom ),
entry_count( stack.entry_count ),
array_capacity( array_capacity ),
array( new Type[array_capacity] ) {
// The above initializations copy the values of the appropriate
// member variables and allocate memory for the data structure;
// however, you must still copy the stored objects.
for(int i = 0; i<array_capacity; i++){
array[i] = stack.array[i];
}
}
template <typename Type>
Drop_off_stack_as_array<Type>::~Drop_off_stack_as_array() {
delete[] array;
}
template <typename Type>
int Drop_off_stack_as_array<Type>::size() const {
return entry_count;
}
template <typename Type>
bool Drop_off_stack_as_array<Type>::full() const {
return (entry_count == array_capacity);
}
template <typename Type>
bool Drop_off_stack_as_array<Type>::empty() const {
return (entry_count == 0);
}
template <typename Type>
Type Drop_off_stack_as_array<Type>::top() const {
if(empty()){
throw underflow();
}
return array[itop];
}
template <typename Type>
void Drop_off_stack_as_array<Type>::swap( Drop_off_stack_as_array<Type> &stack ) {
std::swap( itop, stack.itop );
std::swap( ibottom, stack.ibottom );
std::swap( entry_count, stack.entry_count );
std::swap( array_capacity, stack.array_capacity );
std::swap( array, stack.array );
}
template <typename Type>
Drop_off_stack_as_array<Type> &Drop_off_stack_as_array<Type>::operator = ( Drop_off_stack_as_array<Type> rhs ) {
swap( rhs );
return *this;
}
template <typename Type>
void Drop_off_stack_as_array<Type>::push( Type const &obj ) {
if(full()){
array[ibottom] = 0;
itop = ibottom;
++ibottom;
}
else{
array[itop+1] = obj;
++itop;
++entry_count;
}
}
template <typename Type>
Type Drop_off_stack_as_array<Type>::pop() {
if(empty()){
throw underflow();
}
array[itop] = 0;
--itop;
--entry_count;
}
template <typename Type>
void Drop_off_stack_as_array<Type>::clear() {
delete [] array;
array = new Type(array_capacity);
}
Maybe something like this:
template <typename Type>
Type Drop_off_stack_as_array<Type>::pop() {
if(empty()){
throw underflow();
}
Type result = array[itop]; // Safe a copy of the top element
array[itop] = 0;
--itop;
--entry_count;
return result; // return it (your return type is not void,
// so you need a return statment which returns a value
}
What is strange in your code (and not just in this place) is the = 0 and what you are doing with the itop and ibottom counters/indices/...? But I guess that is another question waiting, your immediate problem is hopefully solved with the above.
(And next time at least include the error message/warning you get in the question, thanks!)
When you write template stack for class T, the class T can be an object and not primitive.
Also, you should not assume that class T has empty constructor, since it is enough for you copy constructor only.
Also, after element popped from stack, you have to release resources. In order to do so, you call destructor.
Please see the example implemented this:
code:
#include <new>
template<typename T>
class stack {
private:
int itop; // points to first free
int size; // maximal capacity
T * array; // memory for data
public:
stack(int n) : itop(0), size(n) {
array = (T *)(new char [sizeof(T) * n]);
}
~stack() {
delete [] (char *)array;
}
void push(const T &obj) {
if (itop < size) {
new (&array [ itop ++ ]) T(obj);
} else {
// error, stack is full
}
}
void pop() {
if (itop > 0) {
array[-- itop] . ~ T();
} else {
// error, stack is empty
}
}
const T &top () {
if (itop > 0) {
return array[( itop - 1)];
} else {
// error, stack is empty
}
}
};