390. CopyConstructible requirements too strict

Section: 20.5.3.1 [utility.arg.requirements] Status: NAD Editorial Submitter: Doug Gregor Opened: 2002-10-24 Last modified: 2016-02-10

Priority: Not Prioritized

View all other issues in [utility.arg.requirements].

View all issues with NAD Editorial status.

Discussion:

The CopyConstructible requirements in Table 30 state that for an object t of type T (where T is CopyConstructible), the expression &t returns the address of t (with type T*). This requirement is overly strict, in that it disallows types that overload operator& to not return a value of type T*. This occurs, for instance, in the Boost.Lambda library, where operator& is overloaded for a Boost.Lambda function object to return another function object.

Example:

  std::vector<int> u, v;
  int x;
  // ...
  std::transform(u.begin(), u.end(), std::back_inserter(v), _1 * x);

_1 * x returns an unnamed function object with operator& overloaded to not return T* , therefore rendering the std::transform call ill-formed. However, most standard library implementations will compile this code properly, and the viability of such binder libraries is severely hindered by the unnecessary restriction in the CopyConstructible requirements.

For reference, the address of an object can be retrieved without using the address-of operator with the following function template:

  template <typename T> T* addressof(T& v)
  {
    return reinterpret_cast<T*>(
         &const_cast<char&>(reinterpret_cast<const volatile char &>(v)));
  }

Note: this relates directly to library issue 350, which will need to be reexamined if the CopyConstructible requirements change.

Proposed resolution:

Remove the last two rows of Table 30, eliminating the requirements that &t and &u return the address of t and u, respectively.

Rationale:

This was a deliberate design decision. Perhaps it should be reconsidered for C++0x.