Opened 14 years ago
Closed 12 years ago
#2857 closed Patches (fixed)
change return type of the c_array() member function
| Reported by: | 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 , 14 years ago
comment:2 by , 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 , 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 , 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 , 13 years ago
| Owner: | changed from to | 
|---|
follow-up: 7 comment:6 by , 13 years ago
| Status: | new → assigned | 
|---|
I will keep an eye on this issue; see what the standards committee decides.
comment:7 by , 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 , 12 years ago
| Milestone: | Boost 1.39.0 → To Be Determined | 
|---|
I've checked get_c_array into the trunk; waiting to see how the tests turn out.
comment:9 by , 12 years ago
| Resolution: | → fixed | 
|---|---|
| Status: | assigned → closed | 
get_c_array is part of the 1.44 release.


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