Opened 14 years ago

Closed 12 years ago

#2857 closed Patches (fixed)

change return type of the c_array() member function

Reported by: hervemart1@… Owned by: Marshall Clow
Milestone: To Be Determined Component: array
Version: Boost 1.38.0 Severity: Cosmetic
Keywords: Cc: niels_address_until_2010-10-10@…

Description

Currently the return type of c_array() member function is T* for boost::array<T,N>. Regarding its name we could expect from this function to return a reference on a C array rather than a pointer on the first element of the array.

In returning T* type a piece of information about the C array is lost since the static size N is not transmitted.

I suggest to change the existing c_array() member function:

T* c_array() { return elems; }

into,

T (&c_array())[N] { return elems; }

The both implementation are pretty similar since a reference on array is implicitly convertible into a pointer on the 1st element of this array.

These following kind of lines of code would still work:

array<int,10> toto;
int* item_ptr = toto.c_array();

but purist would now be able to write

int (&toto_ref)[10] = toto.c_array();

The improvement which would be brought by the change is that in our example sizeof( toto.c_array() ) would return value 10*sizeof(int), the real size of the C array.

best regards, herve

Change History (9)

comment:1 by niels_dekker, 14 years ago

Discussion on this subject: "[boost][array] change proposal for the c_array() function" http://thread.gmane.org/gmane.comp.lib.boost.devel/187487 http://lists.boost.org/Archives/boost/2009/03/149711.php

comment:2 by niels_dekker, 14 years ago

David Abrahams and I just mailed about the issue and we agreed that it would be preferable to have such a function as a non-member. Because tr1::array doesn't have a c_array() member function and std::array probably won't have one either. (See LWG issue 930, Access to std::array data as built-in array type) Such a boost::get_c_array(arg) function could be overloaded to support both std::array and boost::array. So it could be implemented as follows:

  // Specific for boost::array: simply returns its elems data member.
  template <typename T, std::size_t N>
  T(&get_c_array(boost::array<T,N>& arg))[N]
  {
    return arg.elems;
  }

  // Const version.
  template <typename T, std::size_t N>
  const T(&get_c_array(const boost::array<T,N>& arg))[N]
  {
    return arg.elems;
  }

  // Overload for std::array, assuming that std::array will have
  // explicit conversion functions as discussed at the WG21 meeting
  // in Summit, March 2009.
  template <typename T, std::size_t N>
  T(&get_c_array(std::array<T,N>& arg))[N]
  {
    return static_cast<T(&)[N]>(arg);
  }

  // Const version.
  template <typename T, std::size_t N>
  const T(&get_c_array(const std::array<T,N>& arg))[N]
  {
    return static_cast<T(&)[N]>(arg);
  }

When rvalue references are supported, get_c_array could be overloaded for rvalue arrays as well.

comment:3 by niels_dekker, 13 years ago

Update: std::array might still have c_array() member functions, as the proposed resolution of LWG #930 was reconsidered by the Standard Library Working Group in Frankfurt, Saturday, July 18. The proposed resolution currently has status Review.

comment:4 by niels_dekker, 13 years ago

Update: Yesterday, the Standard Library Working Group has discussed my proposal to add c_array() member functions to std::array, in Santa Cruz. Unfortunately: There was not enough consensus that this was sufficiently useful. http://home.roadrunner.com/~hinnant/issue_review/lwg-closed.html#930 So now it is unlikely that std::array will offer an easy way to get a reference to its internal built-in array.

I wonder if it's safe to cast std::array<T,N> to a pointer-to-array, as follows:

static_cast<T(*)[N]>(static_cast<void*>(arr.data()));

comment:5 by Marshall Clow, 13 years ago

Owner: changed from No-Maintainer to Marshall Clow

comment:6 by Marshall Clow, 13 years ago

Status: newassigned

I will keep an eye on this issue; see what the standards committee decides.

in reply to:  6 comment:7 by niels_dekker, 13 years ago

Replying to comment 6:

I will keep an eye on this issue; see what the standards committee decides.

Thanks, Marchall. Unfortunately the standard library issue, LWG #930, Access to std::array data as built-in array type, has been rejected. I do not entirely understand why.

Anyway, a non-member function like get_c_array(array<T,N>&) (as I suggested here before at comment 2) would also be fine to me.

comment:8 by Marshall Clow, 12 years ago

Milestone: Boost 1.39.0To Be Determined

I've checked get_c_array into the trunk; waiting to see how the tests turn out.

comment:9 by Marshall Clow, 12 years ago

Resolution: fixed
Status: assignedclosed

get_c_array is part of the 1.44 release.

Note: See TracTickets for help on using tickets.