Retaining a handle on a std::indirect_array<>

S

Steven T. Hatton

I believe the answer is that the language doesn't support the ability to
retain a reference to a std::indirect_array<>, and would be illadvised to
try, but I figure I'll ask just to be sure. What I mean by retaining a
handle is that I would like to have a class that has a member field
functioning as a reference into a valarray initialized by an
indirect_array.

template<typename T>
class IA{
indirect_array<T>& ia_;
public:
IA(indirect_array<T>& ia_):_ia(ia_){}
}


This code fails with the arcana listed following:

#include <sth/sth_std.hh> // every blinkin' standard header there is

using std::valarray;
using std::indirect_array;
using std::cout;
using std::eek:stream;

template<typename T>
ostream& operator<<(ostream& out, const valarray<T>& va) {
for(size_t i; i < va.size(); i++) {
out << va << " ";
}
return out;
}

template<typename T>
class Indirect {
public:
Indirect(indirect_array<T>& v_ )
:_v(v_)
{}

ostream& print(ostream& out) const {
return out << "Indirect: " << valarray<T>(_v) << "\n";
}

void operator *= (const T& t)
{
_v *= t;
}

protected:
indirect_array<T>& _v;
valarray<size_t>& idx;
};

template<typename T>
ostream& operator<<(ostream& out, const Indirect<T>& i) { return
i.print(out); }

void test() {
double da[9] =
{1.1 , 1.2, 1.3
,2.1, 2.2, 2.3
,3.1, 3.2, 3.3};

valarray<double> v(da,sizeof(da)/sizeof(da[0]));
size_t ia[3] = {0,3,6};
valarray<size_t> idx(ia, sizeof(ia)/sizeof(ia[0]));

Indirect<double> id(v[idx]);
cout << id;
}

int main(){
test();
}

-*- mode: compilation; default-directory: "~/code/c++/scratch/valarray/" -*-
g++ -oindirect indirect.cc -I$CPPSTH -I$BOOST_INCLUDE
indirect.cc: In function `void test()':
indirect.cc:50: error: no matching function for call to `Indirect<double>::
Indirect(std::indirect_array<double>)'
indirect.cc:17: error: candidates are: Indirect<double>::Indirect(const
Indirect<double>&)
indirect.cc:20: error:
Indirect<T>::Indirect(std::indirect_array<_Tp>&) [with T = double]
distcc[2926] ERROR: compile on localhost failed


I believe the penultimate line is telling me to pound sand, but I'm not
sure. Note that I wrote /indirect_array<T>&/ and
not /indirect_array<_Tp>&/.

The alternative I am considering is to maintain an index (actually present
in class Indirect{}) and use that to form the indirect_array on the fly as
needed. That adds significantly to the memory usage, but I can probably
live with it. Is there a better alternative? (I'm aware of slice and
gslice).
--
"If our hypothesis is about anything and not about some one or more
particular things, then our deductions constitute mathematics. Thus
mathematics may be defined as the subject in which we never know what we
are talking about, nor whether what we are saying is true." - Bertrand
Russell
 
T

Tom Widmer

I believe the answer is that the language doesn't support the ability to
retain a reference to a std::indirect_array<>, and would be illadvised to
try, but I figure I'll ask just to be sure.

The standard has a specific (non-normative) note saying that users
should never declare a std::indirect_array - it effect, you should
only use it as an rvalue.

What I mean by retaining a
handle is that I would like to have a class that has a member field
functioning as a reference into a valarray initialized by an
indirect_array. [snip]
-*- mode: compilation; default-directory: "~/code/c++/scratch/valarray/" -*-
g++ -oindirect indirect.cc -I$CPPSTH -I$BOOST_INCLUDE
indirect.cc: In function `void test()':
indirect.cc:50: error: no matching function for call to `Indirect<double>::
Indirect(std::indirect_array<double>)'
indirect.cc:17: error: candidates are: Indirect<double>::Indirect(const
Indirect<double>&)
indirect.cc:20: error:
Indirect<T>::Indirect(std::indirect_array<_Tp>&) [with T = double]
distcc[2926] ERROR: compile on localhost failed


I believe the penultimate line is telling me to pound sand, but I'm not
sure. Note that I wrote /indirect_array<T>&/ and
not /indirect_array<_Tp>&/.

You can't bind a temporary to a non-const reference, as you are
attempting in the line:
Indirect said:
The alternative I am considering is to maintain an index (actually present
in class Indirect{}) and use that to form the indirect_array on the fly as
needed. That adds significantly to the memory usage, but I can probably
live with it. Is there a better alternative? (I'm aware of slice and
gslice).

Yes, instead of holding the indirect_array, you should be holding the
valarray<size_t>, and creating the indirect_array on demand. However,
really you should be using a library that is likely to be more
efficient, like uBLAS. valarray is very hard to use efficiently, since
potentially arrays are copied unnecessarily all the time.

Tom
 
B

Benjamin Lau

With reference to your class declaration Steven:
template<typename T>
class IA{
indirect_array<T>& ia_;
public:
IA(indirect_array<T>& ia_):_ia(ia_){}
}

Your constructor is initializing the member refernce _ia with ia_,
however _ia doesn't exist, and you also lack a semicolon after the
closing brace. Here's a revised piece of code to clarify what I mean:
template<typename T>
class IA{
indirect_array<T>& ia_;
public:
IA(indirect_array<T>& _ia):ia_(_ia){}
}; //i changed the parameter name from ia_ to _ia so that there will
be no name
//conflicts with the member reference

This may not have helped you solve your problem but I hope that it is
helpful to you. :)

Benjamin Lau
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,772
Messages
2,569,593
Members
45,111
Latest member
KetoBurn
Top