Reputation: 210755
This question is easiest to illustrate with an example, so here goes:
(Not all implementations actually compile it correctly, but I'm wondering if that's a bug.)
#include <algorithm>
class Picky
{
friend
Picky *std::copy<Picky const *, Picky *>(Picky const *, Picky const *, Picky *);
Picky &operator =(Picky const &) { return *this; }
public:
Picky() { }
};
int main()
{
Picky const a;
Picky b;
std::copy<Picky const *, Picky *>(&a, &a + 1, &b);
return 0;
}
Upvotes: 8
Views: 174
Reputation: 137394
std::copy
requires an output iterator ([algorithms.general]/p5); output iterators, among other things, require *r = o
to be valid ([output.iterators], Table 108) - not just "valid sometimes" or "valid in some contexts".
Since for Picky *p, a;
, *p = a
isn't valid in most contexts, Picky *
isn't a valid output iterator.
Hmm it'd be great if you could generalize your answer to other things beyond the particular example I gave. Like, for example,
std::vector::push_back(T const &)
, or whatever.
Befriending a member function is an absolute no-no, because you aren't even guaranteed that there's a member function with that signature ([member.functions]/p2, which Stephan T. Lavavej calls the "STL Implementers Can Be Sneaky Rule"):
An implementation may declare additional non-virtual member function signatures within a class:
- by adding arguments with default values to a member function signature187 [Note: An implementation may not add arguments with default values to virtual, global, or non-member functions. — end note];
- by replacing a member function signature with default values by two or more member function signatures with equivalent behavior; and
- by adding a member function signature for a member function name.
187 Hence, the address of a member function of a class in the C++ standard library has an unspecified type.
Upvotes: 8
Reputation: 36617
The code might compile if std::copy()
does not call any other non-friend functions but I've yet to encounter any such implementation. And there is no requirement in the standard limiting HOW std::copy()
achieves the required effect.
However, it does require a working and accessible assignment operator.
Upvotes: 1