Retaining a handle on a std::indirect_array<>

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Steven T. Hatton

    #1

    Retaining a handle on a std::indirect_array<>

    I believe the answer is that the language doesn't support the ability to
    retain a reference to a std::indirect_a rray<>, 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<typena me T>
    class IA{
    indirect_array< T>& ia_;
    public:
    IA(indirect_arr ay<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_a rray;
    using std::cout;
    using std::ostream;

    template<typena me T>
    ostream& operator<<(ostr eam& out, const valarray<T>& va) {
    for(size_t i; i < va.size(); i++) {
    out << va[i] << " ";
    }
    return out;
    }

    template<typena me T>
    class Indirect {
    public:
    Indirect(indire ct_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<typena me T>
    ostream& operator<<(ostr eam& 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<doubl e>::
    Indirect(std::i ndirect_array<d ouble>)'
    indirect.cc:17: error: candidates are: Indirect<double >::Indirect(con st
    Indirect<double >&)
    indirect.cc:20: error:
    Indirect<T>::In direct(std::ind irect_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

  • Tom Widmer

    #2
    Re: Retaining a handle on a std::indirect_a rray&lt;&gt;

    On Wed, 10 Nov 2004 03:31:26 -0500, "Steven T. Hatton"
    <susudata@setid ava.kushan.aa> wrote:
    [color=blue]
    >I believe the answer is that the language doesn't support the ability to
    >retain a reference to a std::indirect_a rray<>, and would be illadvised to
    >try, but I figure I'll ask just to be sure.[/color]

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

    What I mean by retaining a[color=blue]
    >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 .[/color]
    [snip][color=blue]
    >-*- 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<doubl e>::
    > Indirect(std::i ndirect_array<d ouble>)'
    >indirect.cc:17 : error: candidates are: Indirect<double >::Indirect(con st
    > Indirect<double >&)
    >indirect.cc:20 : error:
    > Indirect<T>::In direct(std::ind irect_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>&/.[/color]

    You can't bind a temporary to a non-const reference, as you are
    attempting in the line:
    Indirect<double > id(v[idx]); //v[idx] returns a temporary
    [color=blue]
    >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).[/color]

    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

    Comment

    • Benjamin Lau

      #3
      Re: Retaining a handle on a std::indirect_a rray&lt;&gt;

      With reference to your class declaration Steven:
      template<typena me T>
      class IA{
      indirect_array< T>& ia_;
      public:
      IA(indirect_arr ay<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<typena me T>
      class IA{
      indirect_array< T>& ia_;
      public:
      IA(indirect_arr ay<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

      Comment

      Working...