Copy-less initialization of a TR1 array

Discussion in 'C++' started by zr, Nov 10, 2008.

  1. zr

    zr Guest

    Hi,

    Is there a way to initialize a std::tr1::array with a pre-allocated
    built-in array in a copy-less assignment, such that both will point to
    the same memory?
    Vice-versa is easy to do, simply use std::t1::array::data() and assign
    the returned value to the c-style pointer;

    if STL does not support this, is there any other library that has such
    a container (maybe BOOST)?

    Here is an example of what i have in mind:

    #include <array>
    using namespace std::tr1;

    int main()
    {

    int cArray[] = { 1 , 2, 3, 4};

    array<int,4> tr1Array(cArray); // Using some imaginary c-tor. Don't
    want to copy. Want to use preallocated memory

    tr1Array[0] = 42;
    assert(tr1Array[0] == cArray[0] == 42); // Both point to same memory

    tr1Array[100] = 42; //In debug builds, this should raise an exception
    cArray[100] = 42; //Much harder to catch

    return 0;
    }
     
    zr, Nov 10, 2008
    #1
    1. Advertising

  2. On Nov 10, 12:30 pm, zr <> wrote:

    > Is there a way to initialize a std::tr1::array with a pre-allocated
    > built-in array in a copy-less assignment, such that both will point to
    > the same memory?


    There is a way. Disclaimer: it is not blessed by the standard.

    > Vice-versa is easy to do, simply use std::t1::array::data() and assign
    > the returned value to the c-style pointer;
    >
    > if STL does not support this, is there any other library that has such
    > a container (maybe BOOST)?
    >
    > Here is an example of what i have in mind:
    >
    > #include <array>
    > using namespace std::tr1;
    >
    > int main()
    > {
    >
    > int cArray[] = { 1 , 2, 3, 4};
    >
    > array<int,4> tr1Array(cArray); // Using some imaginary c-tor. Don't
    > want to copy. Want to use preallocated memory


    Here you do:

    // make sure that the binary layouts of
    // array<> and C-array are the same
    typedef int static_assert[sizeof(array<int,4>) == sizeof(cArray) ?
    1 : -1];
    // now do the hack
    array<int,4>& tr1Array = reinterpret_cast<array<int,4>&>(cArray);

    > tr1Array[0] = 42;
    > assert(tr1Array[0] == cArray[0] == 42); // Both point to same memory
    >
    > tr1Array[100] = 42; //In debug builds, this should raise an exception
    > cArray[100] = 42; //Much harder to catch
    >
    > return 0;
    >
    > }


    --
    Max
     
    Maxim Yegorushkin, Nov 10, 2008
    #2
    1. Advertising

  3. zr

    zr Guest

    On Nov 10, 3:52 pm, Maxim Yegorushkin <>
    wrote:
    > On Nov 10, 12:30 pm, zr <> wrote:
    >
    > > Is there a way to initialize a std::tr1::array with a pre-allocated
    > > built-in array in a copy-less assignment, such that both will point to
    > > the same memory?

    >
    > There is a way. Disclaimer: it is not blessed by the standard.
    >
    >
    >
    > > Vice-versa is easy to do, simply use std::t1::array::data() and assign
    > > the returned value to the c-style pointer;

    >
    > > if STL does not support this, is there any other library that has such
    > > a container (maybe BOOST)?

    >
    > > Here is an example of what i have in mind:

    >
    > > #include <array>
    > > using namespace std::tr1;

    >
    > > int main()
    > > {

    >
    > > int cArray[] = { 1 , 2, 3, 4};

    >
    > > array<int,4> tr1Array(cArray); // Using some imaginary c-tor. Don't
    > > want to copy. Want to use preallocated memory

    >
    > Here you do:
    >
    >     // make sure that the binary layouts of
    >     // array<> and C-array are the same
    >     typedef int static_assert[sizeof(array<int,4>) == sizeof(cArray) ?
    > 1 : -1];
    >     // now do the hack
    >     array<int,4>& tr1Array = reinterpret_cast<array<int,4>&>(cArray);
    >
    > > tr1Array[0] = 42;
    > > assert(tr1Array[0] == cArray[0] == 42); // Both point to same memory

    >
    > > tr1Array[100] = 42; //In debug builds, this should raise an exception
    > > cArray[100] = 42; //Much harder to catch

    >
    > > return 0;

    >
    > > }

    >
    > --
    > Max


    Thanks, Max. I wonder if there is a similar trick for casting a
    dynamic array to a std::vector...
     
    zr, Nov 10, 2008
    #3
  4. zr

    Guest

    On Nov 10, 7:30 am, zr <> wrote:
    > Hi,
    >
    > Is there a way to initialize a std::tr1::array with a pre-allocated
    > built-in array in a copy-less assignment, such that both will point to
    > the same memory?
    > Vice-versa is easy to do, simply use std::t1::array::data() and assign
    > the returned value to the c-style pointer;
    >
    > if STL does not support this, is there any other library that has such
    > a container (maybe BOOST)?
    >
    > Here is an example of what i have in mind:
    >
    > #include <array>
    > using namespace std::tr1;
    >
    > int main()
    > {
    >
    > int cArray[] = { 1 , 2, 3, 4};
    >
    > array<int,4> tr1Array(cArray); // Using some imaginary c-tor. Don't
    > want to copy. Want to use preallocated memory
    >
    > tr1Array[0] = 42;
    > assert(tr1Array[0] == cArray[0] == 42); // Both point to same memory
    >
    > tr1Array[100] = 42; //In debug builds, this should raise an exception
    > cArray[100] = 42; //Much harder to catch
    >
    > return 0;
    >
    >
    >
    > }- Hide quoted text -
    >
    > - Show quoted text -


    The issue with doing that is that once you have a container, you
    should be able to do whatever you want with it (e.g. changing it's
    elements). So unless you put it behind an interface (e.g. a function
    or class) that returns a const container, it won't work.

    You can use constant built in arrays by passing around a pair of it's
    begin and end const iterators. Client code that uses it only knows
    that it's a const container and has no knowledge of what kind of
    container.

    HTH
     
    , Nov 10, 2008
    #4
  5. On Nov 10, 12:30 pm, zr <> wrote:
    > Hi,
    >
    > Is there a way to initialize a std::tr1::array with a pre-allocated
    > built-in array in a copy-less assignment, such that both will point to
    > the same memory?


    Yes, you can use 'placement new':

    typedef array <int, 4> A;
    int init [] = {1, 2, 3, 4};
    A& a = *new (init) A;

    Of course, this is equivalent to

    array <int, 4> a = {1, 2, 3, 4};

    Regards,
    Vidar Hasfjord
     
    Vidar Hasfjord, Nov 10, 2008
    #5
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Emmanuel Deloget
    Replies:
    3
    Views:
    412
    Chris Thomasson
    Mar 3, 2007
  2. zr
    Replies:
    2
    Views:
    529
  3. jiajia wu
    Replies:
    0
    Views:
    372
    jiajia wu
    Oct 1, 2009
  4. 6668
    Replies:
    0
    Views:
    165
  5. lllll
    Replies:
    0
    Views:
    151
    lllll
    Jun 8, 2009
Loading...

Share This Page