473,386 Members | 1,702 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,386 software developers and data experts.

inhomogeneous container

Hi,

I have an array class (the blitz library actually) which looks like this:

template<typename P_numtype, int N_rank>
class Array : public MemoryBlockReference<P_numtype>
, public ETBase<Array<P_numtype,N_rank> >
{
// ... code
};
I would like to create a container class which allows me to store
Array<T,N> objects of different rank N and same data type T. The
container should have [](int i) operators which would return a reference
at i-th array.
My questions would be how could I deduce the returned type of the
operator [](int) and what should I use to store the arrays ?

template<class T_numtype>
class ArrayPool{

public:

Array<T_numtype, N_rank ??? > operator[](int i)
{
// ... return i-th array from pool
}

private:
// ... data

};
Thanks in advance.
Jun 22 '06 #1
3 1695
Valeriu Catina wrote:
Hi,

I have an array class (the blitz library actually) which looks like this:

template<typename P_numtype, int N_rank>
class Array : public MemoryBlockReference<P_numtype>
, public ETBase<Array<P_numtype,N_rank> >
{
// ... code
};
I would like to create a container class which allows me to store
Array<T,N> objects of different rank N and same data type T. The
container should have [](int i) operators which would return a reference
at i-th array.
My questions would be how could I deduce the returned type of the
operator [](int) and what should I use to store the arrays ?

template<class T_numtype>
class ArrayPool{

public:

Array<T_numtype, N_rank ??? > operator[](int i)
{
// ... return i-th array from pool
}

private:
// ... data

};
Thanks in advance.


Obviously there is no sensible return for operator[] as you've defined
it. Assuming you cannot modify the Array class, probably your best
option is to return a type that exposes the interface of Array<T, N>,
but does not have any template parameters itself, and allows you to
query for N. This requires several stages of indirection, which I will
now describe:

1) Create a class that exposes the same interface as Array<T, N> (and
anything else you'd want to do, such as querying rank), but consists of
only pure virtual functions. This class will also need a "clone"
function, for reasons that will become apparent. In the example code
below this is called ArrayTImplBase.

2) Create a class template (on T and N) that has data member of type
Array<T, N> and inherits from the class created in step 1. This class
should implement the inherited virtual functions by forwarding them to
the data member. In the example code this is called ArrayTImpl.

3) Create a class that exposes the same interface as that in step 1, and
can be constructed from an instance of Array<T, N> (i.e., the
constructor is templated, not the class). This class will use the PIMPL
idiom to manage an object of type ArrayTImpl<T, N> (and therefore an
object of type Array<T, N>). If you want to store these in a standard
container (which was the whole point), then you MUST implement a copy
constructor and operator=. This is why it was necessary to create a
clone function. In the example code this is called ArrayT.
While I haven't done exhaustive testing, I think the following
represents a minimal working example:
#include <cstddef> // for std::size_t
#include <algorithm> // for std::swap

template <typename T, std::size_t N>
class Array
{
public:
int f1()
{
return 1 ;
}

int f2()
{
return 2 ;
}

int f3()
{
return 3 ;
}
} ;

class ArrayTImplBase
{
public:
virtual std::size_t rank() const = 0 ;
virtual ArrayTImplBase * clone() = 0 ;
virtual ~ArrayTImplBase()
{}

virtual int f1() = 0 ;
virtual int f2() = 0 ;
virtual int f3() = 0 ;
} ;

template <typename T, std::size_t N>
class ArrayTImpl : public ArrayTImplBase
{
public:
std::size_t rank() const
{
return N ;
}

ArrayTImpl<T, N> * clone()
{
return new ArrayTImpl(array_) ;
}

ArrayTImpl(const Array<T, N> & array)
: array_(array)
{}

int f1()
{
return array_.f1() ;
}

int f2()
{
return array_.f2() ;
}

int f3()
{
return array_.f3() ;
}

private:
Array<T, N> array_ ;
} ;

template <typename T>
class ArrayT
{
public:

template <std::size_t N>
explicit ArrayT(const Array<T, N> & array)
: pimpl_(new ArrayTImpl<T, N>(array))
{}

ArrayT(const ArrayT & a)
: pimpl_(a.pimpl_->clone())
{}

ArrayT & operator=(const ArrayT & a)
{
ArrayTImplBase * p = a.pimpl_->clone() ;
std::swap(p, pimpl_) ;
delete p ;
}

~ArrayT()
{
delete pimpl_ ;
}

std::size_t rank() const
{
return pimpl_->rank() ;
}

int f1()
{
return pimpl_->f1() ;
}

int f2()
{
return pimpl_->f2() ;
}

int f3()
{
return pimpl_->f3() ;
}

private:

ArrayTImplBase * pimpl_ ;
} ;
--
Alan Johnson
Jun 22 '06 #2
Alan Johnson wrote:
While I haven't done exhaustive testing, I think the following
represents a minimal working example:

[lots of code removed]

One minor correction. ArrayT's operator= should end with "return *this ;".

Also, a usage example:

#include <vector>

int main()
{
std::vector< ArrayT<int> > v ;

v.push_back(ArrayT<int>(Array<int, 5>())) ;
v.push_back(ArrayT<int>(Array<int, 100>())) ;
v.push_back(ArrayT<int>(Array<int, 20>())) ;

v[0].f1() ;
v[0].f2() ;
v[0].f3() ;
// Do whatever.
}

--
Alan Johnson
Jun 22 '06 #3
Alan Johnson wrote:
Alan Johnson wrote:
While I haven't done exhaustive testing, I think the following
represents a minimal working example:

[lots of code removed]

One minor correction. ArrayT's operator= should end with "return *this ;".

Also, a usage example:

#include <vector>

int main()
{
std::vector< ArrayT<int> > v ;

v.push_back(ArrayT<int>(Array<int, 5>())) ;
v.push_back(ArrayT<int>(Array<int, 100>())) ;
v.push_back(ArrayT<int>(Array<int, 20>())) ;

v[0].f1() ;
v[0].f2() ;
v[0].f3() ;
// Do whatever.
}


Thanks for your hints,

actually I have some functions whose arguments are arrays of different rank:

void some_func(Array<double,4>& A, Array<double,4>& B,
Array<double,3>& C, Array<double,2>& D, Array<double,2>& E);

I just don't like functions with many arguments and my initial idea was
to create an array container and to pass it as argument to my functions.

So far I cannot think of a more elegant way to write these functions and
ellipsis are out of question.

Any other suggestion is welcome.

Bye,

V. Catina.


Jun 23 '06 #4

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Maitre Bart | last post by:
What I want to perform is calling a member function of container 1 (CRunner), using as argument the value of a container 2 (CNames). The purpose is to transfer values from C2 into C1 using a...
3
by: jignesh shah | last post by:
Hi all, Is there a way to recover a single container if its been corrupted or mark bad without restoring whole tablespace? environment: db28.1/aix5.1/tsm/rs-6000. Regards Jignesh
1
by: glen stark | last post by:
Hi everyone. I would like to consider the following problem: I want to provide the ability to store and manipulate numeric container classes that provide 1) element wise access 2) size but...
9
by: horizon5 | last post by:
Hi, my collegues and I recently held a coding style review. All of the code we produced is used in house on a commerical project. One of the minor issues I raised was the common idiom of...
7
by: toton | last post by:
Hi, I want a circular buffer or queue like container (queue with array implementation). Moreover I want random access over the elements. And addition at tail and remove from head need to be low...
11
by: food4uk | last post by:
Dear all : I am not good at programming, please give a hand. My data structure is very similar as an array. I actually can use the std::vector as container to organize my data objects. However,...
2
by: Daniel Lipovetsky | last post by:
I would like for an object to "report" to a container object when a new instance is created or deleted. I could have a container object that is called when a new instance is created, as below. ...
18
by: Goran | last post by:
Hi @ all! Again one small question due to my shakiness of what to use... What is better / smarter? private: vector<MyClass_t* itsVector; OR...
36
by: Peter Olcott | last post by:
So far the only way that I found to do this was by making a single global instance of the container class and providing access to the contained class, through this single global instance. Are...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.